@@ -12,14 +12,15 @@ module Network.HTTP.Affjax
1212 , delete , delete_
1313 ) where
1414
15- import Control.Monad.Aff (Aff (), makeAff )
15+ import Control.Monad.Aff (Aff (), makeAff , makeAff' , Canceler () )
1616import Control.Monad.Eff (Eff ())
1717import Control.Monad.Eff.Exception (Error (), error )
1818import Data.Either (Either (..))
1919import Data.Foreign (Foreign (..), F ())
20- import Data.Function (Fn4 (), runFn4 )
20+ import Data.Function (Fn5 (), runFn5 , Fn4 (), runFn4 )
2121import Data.Maybe (Maybe (..), maybe )
2222import Data.Nullable (Nullable (), toNullable )
23+ import DOM.XHR (XMLHttpRequest ())
2324import Network.HTTP.Affjax.Request
2425import Network.HTTP.Affjax.Response
2526import Network.HTTP.Affjax.ResponseType
@@ -66,7 +67,7 @@ type URL = String
6667
6768-- | Makes an `Affjax` request.
6869affjax :: forall e a b . (Requestable a , Responsable b ) => AffjaxRequest a -> Affjax e b
69- affjax = makeAff <<< affjax'
70+ affjax = makeAff' <<< affjax'
7071
7172-- | Makes a `GET` request to the specified URL.
7273get :: forall e a . (Responsable a ) => URL -> Affjax e a
@@ -121,9 +122,9 @@ affjax' :: forall e a b. (Requestable a, Responsable b) =>
121122 AffjaxRequest a ->
122123 (Error -> Eff (ajax :: Ajax | e ) Unit ) ->
123124 (AffjaxResponse b -> Eff (ajax :: Ajax | e ) Unit ) ->
124- Eff (ajax :: Ajax | e ) Unit
125+ Eff (ajax :: Ajax | e ) ( Canceler ( ajax :: Ajax | e ))
125126affjax' req eb cb =
126- runFn4 unsafeAjax responseHeader req' eb cb'
127+ runFn5 _ajax responseHeader req' cancelAjax eb cb'
127128 where
128129 req' :: AjaxRequest
129130 req' = { method: methodToString req.method
@@ -149,9 +150,9 @@ type AjaxRequest =
149150 , password :: Nullable String
150151 }
151152
152- foreign import unsafeAjax
153+ foreign import _ajax
153154 " " "
154- function unsafeAjax (mkHeader, options, errback, callback) {
155+ function _ajax (mkHeader, options, canceler , errback, callback) {
155156 return function () {
156157 var xhr = new XMLHttpRequest();
157158 xhr.open(options.method || " GET " , options.url || " /" , true, options.username, options.password);
@@ -179,10 +180,29 @@ foreign import unsafeAjax
179180 };
180181 xhr.responseType = options.responseType;
181182 xhr.send(options.content);
183+ return canceler(xhr);
182184 };
183185 }
184- " " " :: forall e a . Fn4 (String -> String -> ResponseHeader )
186+ " " " :: forall e a . Fn5 (String -> String -> ResponseHeader )
185187 AjaxRequest
188+ (XMLHttpRequest -> Canceler (ajax :: Ajax | e ))
186189 (Error -> Eff (ajax :: Ajax | e ) Unit )
187190 (AffjaxResponse Foreign -> Eff (ajax :: Ajax | e ) Unit )
188- (Eff (ajax :: Ajax | e ) Unit )
191+ (Eff (ajax :: Ajax | e ) (Canceler (ajax :: Ajax | e )))
192+
193+ cancelAjax :: forall e . XMLHttpRequest -> Canceler (ajax :: Ajax | e )
194+ cancelAjax xhr err = makeAff (\eb cb -> runFn4 _cancelAjax xhr err eb cb)
195+
196+ foreign import _cancelAjax
197+ " " "
198+ function _cancelAjax (xhr, cancelError, errback, callback) {
199+ return function () {
200+ try { xhr.abort(); } catch (e) { return errback(e)(); }
201+ return callback(true)();
202+ };
203+ };
204+ " " " :: forall e . Fn4 XMLHttpRequest
205+ Error
206+ (Error -> Eff (ajax :: Ajax | e ) Unit )
207+ (Boolean -> Eff (ajax :: Ajax | e ) Unit )
208+ (Eff (ajax :: Ajax | e ) Unit )
0 commit comments