Skip to content

Commit

Permalink
Wait for the popping confirmation to arrive before pushing anything t…
Browse files Browse the repository at this point in the history
…o history
  • Loading branch information
mkhatib committed Oct 14, 2016
1 parent 43828ce commit 27f10e9
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 24 deletions.
17 changes: 4 additions & 13 deletions examples/viewer.html
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@
throw new Error('Only one step push allowed');
}
this.stackIndex_ = stackIndex;
window.history.pushState({stackIndex: stackIndex}, '');
window.history.pushState({}, '');
return Promise.resolve();
};

Expand All @@ -385,18 +385,9 @@
if (this.visibilityState_ != 'visible') {
return;
}
console.log('popping: ', e.state);
var poppedIndex = e.state && e.state.stackIndex;

if (poppedIndex <= this.stackIndex_) {
// Going Back in history.
// Even more trivial. Always assumes that only one step was popped in
// history.
this.stackIndex_--;
} else {
// Going Forward in history.
this.stackIndex_++;
}
// Even more trivial. Always assumes that only one step was popped in
// history.
this.stackIndex_--;
this.sendRequest_('historyPopped', {
newStackIndex: this.stackIndex_
}, false);
Expand Down
8 changes: 3 additions & 5 deletions src/document-click.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,9 @@ export function onDocumentElementClick_(
}

if (tgtLoc.hash != curLoc.hash) {
timerFor(win).delay(() => {
// Push/pop history.
history.push(() => {
win.location.replace(`${curLoc.hash || '#'}`);
});
}, 1000);
history.push(() => {
win.location.replace(`${curLoc.hash || '#'}`);
});
}
}
37 changes: 31 additions & 6 deletions src/service/history-impl.js
Original file line number Diff line number Diff line change
Expand Up @@ -573,8 +573,12 @@ export class HistoryBindingVirtual_ {

/**
* @param {!./viewer-impl.Viewer} viewer
* @param {!Window} win
*/
constructor(viewer) {
constructor(viewer, win) {
/** @private @const {!../service/timer-impl.Timer} */
this.timer_ = timerFor(win);

/** @private @const */
this.viewer_ = viewer;

Expand All @@ -587,6 +591,12 @@ export class HistoryBindingVirtual_ {
/** @private {!UnlistenDef} */
this.unlistenOnHistoryPopped_ = this.viewer_.onHistoryPoppedEvent(
this.onHistoryPopped_.bind(this));

/** @private {!Promise} */
this.awaitPoppingPromise_ = Promise.resolve();

/** @private {!function(*)) */
this.awaitPoppingPromiseResolver_ = null;
}

/** @override */
Expand All @@ -601,14 +611,25 @@ export class HistoryBindingVirtual_ {

/** @override */
push() {
// Current implementation doesn't wait for response from viewer.
this.updateStackIndex_(this.stackIndex_ + 1);
this.viewer_.postPushHistory(this.stackIndex_);
return Promise.resolve(this.stackIndex_);
// Waiting for popping confirmation to happen otherwise a race condition
// between popping and pushing might happen causing history to be messed
// up. This will only wait 100ms to avoid getting stuck if confirmation
// never arrived.
return Promise.race([this.timer_.promise(100), this.awaitPoppingPromise_])
.then(() => {
// Current implementation doesn't wait for response from viewer.
this.updateStackIndex_(this.stackIndex_ + 1);
this.viewer_.postPushHistory(this.stackIndex_);
return Promise.resolve(this.stackIndex_);
});
}

/** @override */
pop(stackIndex) {
this.awaitPoppingPromise_ = new Promise(resolve => {
this.awaitPoppingPromiseResolver_ = resolve;
});

if (stackIndex > this.stackIndex_) {
return Promise.resolve(this.stackIndex_);
}
Expand All @@ -623,6 +644,10 @@ export class HistoryBindingVirtual_ {
*/
onHistoryPopped_(event) {
this.updateStackIndex_(event.newStackIndex);
if (this.awaitPoppingPromiseResolver_) {
this.awaitPoppingPromiseResolver_();
this.awaitPoppingPromiseResolver_ = null;
}
}

/**
Expand Down Expand Up @@ -652,7 +677,7 @@ function createHistory(ampdoc) {
let binding;
if (viewer.isOvertakeHistory() || getMode(ampdoc.win).test ||
ampdoc.win.AMP_TEST_IFRAME) {
binding = new HistoryBindingVirtual_(viewer);
binding = new HistoryBindingVirtual_(viewer, ampdoc.win);
} else {
// Only one global "natural" binding is allowed since it works with the
// global history stack.
Expand Down

0 comments on commit 27f10e9

Please sign in to comment.