Bug 994146: panel should be reset when closed, r=dmose

This commit is contained in:
Nicolas Perriault
2014-05-29 21:13:45 +01:00
parent 1f35fcd35c
commit bb39e618b0
2 changed files with 129 additions and 2 deletions

View File

@@ -103,11 +103,58 @@ loop.panel = (function(_, mozL10n) {
});
var PanelRouter = loop.shared.router.BaseRouter.extend({
/**
* DOM document object.
* @type {HTMLDocument}
*/
document: undefined,
routes: {
"": "home"
},
initialize: function(options) {
options = options || {};
if (!options.document) {
throw new Error("missing required document");
}
this.document = options.document;
this._registerVisibilityChangeEvent();
this.on("panel:open panel:closed", this.reset, this);
},
/**
* Register the DOM visibility API event for the whole document, and trigger
* appropriate events accordingly:
*
* - `panel:opened` when the panel is open
* - `panel:closed` when the panel is closed
*
* @link http://www.w3.org/TR/page-visibility/
*/
_registerVisibilityChangeEvent: function() {
this.document.addEventListener("visibilitychange", function(event) {
this.trigger(event.currentTarget.hidden ? "panel:closed"
: "panel:open");
}.bind(this));
},
/**
* Default entry point.
*/
home: function() {
this.reset();
},
/**
* Resets this router to its initial state.
*/
reset: function() {
// purge pending notifications
this._notifier.clear();
// reset home view
this.loadView(new PanelView({notifier: this._notifier}));
}
});
@@ -117,6 +164,7 @@ loop.panel = (function(_, mozL10n) {
*/
function init() {
router = new PanelRouter({
document: document,
notifier: new sharedViews.NotificationListView({el: "#messages"})
});
Backbone.history.start();

View File

@@ -11,6 +11,13 @@ describe("loop.panel", function() {
var sandbox, notifier, fakeXHR, requests = [];
function createTestRouter(fakeDocument) {
return new loop.panel.PanelRouter({
notifier: notifier,
document: fakeDocument
});
}
beforeEach(function() {
sandbox = sinon.sandbox.create();
fakeXHR = sandbox.useFakeXMLHttpRequest();
@@ -41,25 +48,97 @@ describe("loop.panel", function() {
new loop.panel.PanelRouter();
}).to.Throw(Error, /missing required notifier/);
});
it("should require a document", function() {
expect(function() {
new loop.panel.PanelRouter({notifier: notifier});
}).to.Throw(Error, /missing required document/);
});
});
describe("constructed", function() {
var router;
beforeEach(function() {
router = new loop.panel.PanelRouter({notifier: notifier});
router = createTestRouter({
hidden: true,
addEventListener: sandbox.spy()
});
sandbox.stub(router, "loadView");
});
describe("#home", function() {
it("should load the PanelView", function() {
it("should reset the PanelView", function() {
sandbox.stub(router, "reset");
router.home();
sinon.assert.calledOnce(router.reset);
});
});
describe("#reset", function() {
it("should clear all pending notifications", function() {
router.reset();
sinon.assert.calledOnce(notifier.clear);
});
it("should load the home view", function() {
router.reset();
sinon.assert.calledOnce(router.loadView);
sinon.assert.calledWithExactly(router.loadView,
sinon.match.instanceOf(loop.panel.PanelView));
});
});
describe("Events", function() {
it("should listen to document visibility changes", function() {
var fakeDocument = {
hidden: true,
addEventListener: sandbox.spy()
};
var router = createTestRouter(fakeDocument);
sinon.assert.calledOnce(fakeDocument.addEventListener);
sinon.assert.calledWith(fakeDocument.addEventListener,
"visibilitychange");
});
it("should trigger panel:open when the panel document is visible",
function(done) {
var router = createTestRouter({
hidden: false,
addEventListener: function(name, cb) {
setTimeout(function() {
cb({currentTarget: {hidden: false}});
}, 0);
}
});
router.once("panel:open", function() {
done();
});
});
it("should trigger panel:closed when the panel document is hidden",
function(done) {
var router = createTestRouter({
addEventListener: function(name, cb) {
hidden: true,
setTimeout(function() {
cb({currentTarget: {hidden: true}});
}, 0);
}
});
router.once("panel:closed", function() {
done();
});
});
});
});
});