From a6e4a012ff76e3f121c68c45637a829b7ded87d2 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Thu, 16 Feb 2012 23:47:52 +0000 Subject: [PATCH] Refactor to use a more formal state machine. --- .../poltergeist/client/browser.coffee | 28 +++++++++---------- .../poltergeist/client/compiled/browser.js | 27 ++++++++---------- 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/lib/capybara/poltergeist/client/browser.coffee b/lib/capybara/poltergeist/client/browser.coffee index 7c19355..6992ae7 100644 --- a/lib/capybara/poltergeist/client/browser.coffee +++ b/lib/capybara/poltergeist/client/browser.coffee @@ -1,19 +1,23 @@ class Poltergeist.Browser constructor: (@owner) -> - @awaiting_response = false + @state = 'default' this.resetPage() resetPage: -> @page.release() if @page? @page = new Poltergeist.WebPage + + @page.onLoadStarted = => + @state = 'loading' if @state == 'clicked' + @page.onLoadFinished = (status) => - if @awaiting_response + if @state == 'loading' @owner.sendResponse(status) - @awaiting_response = false + @state = 'default' visit: (url) -> - @awaiting_response = true + @state = 'loading' @page.open(url) current_url: -> @@ -88,14 +92,9 @@ class Poltergeist.Browser @owner.sendResponse(true) click: (id) -> - load_detected = false - - # Detect if the click event triggers a page load. If it does, don't send - # a response here, because the response will be sent once the page has loaded. - @page.onLoadStarted = => - return if load_detected - @awaiting_response = true - load_detected = true + # If the click event triggers onLoadStarted, we will transition to the 'loading' + # state and wait for onLoadFinished before sending a response. + @state = 'clicked' @page.get(id).click() @@ -103,8 +102,9 @@ class Poltergeist.Browser # callback can (possibly) fire, before we decide whether to send a response. setTimeout( => - @page.onLoadStarted = null - @owner.sendResponse(true) unless load_detected + if @state == 'clicked' + @state = 'default' + @owner.sendResponse(true) , 10 ) diff --git a/lib/capybara/poltergeist/client/compiled/browser.js b/lib/capybara/poltergeist/client/compiled/browser.js index 490b05c..8f7487b 100644 --- a/lib/capybara/poltergeist/client/compiled/browser.js +++ b/lib/capybara/poltergeist/client/compiled/browser.js @@ -2,7 +2,7 @@ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments) Poltergeist.Browser = (function() { function Browser(owner) { this.owner = owner; - this.awaiting_response = false; + this.state = 'default'; this.resetPage(); } Browser.prototype.resetPage = function() { @@ -10,15 +10,20 @@ Poltergeist.Browser = (function() { this.page.release(); } this.page = new Poltergeist.WebPage; + this.page.onLoadStarted = __bind(function() { + if (this.state === 'clicked') { + return this.state = 'loading'; + } + }, this); return this.page.onLoadFinished = __bind(function(status) { - if (this.awaiting_response) { + if (this.state === 'loading') { this.owner.sendResponse(status); - return this.awaiting_response = false; + return this.state = 'default'; } }, this); }; Browser.prototype.visit = function(url) { - this.awaiting_response = true; + this.state = 'loading'; return this.page.open(url); }; Browser.prototype.current_url = function() { @@ -86,19 +91,11 @@ Poltergeist.Browser = (function() { return this.owner.sendResponse(true); }; Browser.prototype.click = function(id) { - var load_detected; - load_detected = false; - this.page.onLoadStarted = __bind(function() { - if (load_detected) { - return; - } - this.awaiting_response = true; - return load_detected = true; - }, this); + this.state = 'clicked'; this.page.get(id).click(); return setTimeout(__bind(function() { - this.page.onLoadStarted = null; - if (!load_detected) { + if (this.state === 'clicked') { + this.state = 'default'; return this.owner.sendResponse(true); } }, this), 10);