Skip to content

Commit

Permalink
New http continuation support
Browse files Browse the repository at this point in the history
  • Loading branch information
jmarnold committed Jul 2, 2012
1 parent 683782f commit 9f6e008
Show file tree
Hide file tree
Showing 12 changed files with 379 additions and 156 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -22,4 +22,5 @@ src/packages
*.dotCover
src/*/repositories.config
.bottle-alias
results
results
chromedriver.log
135 changes: 0 additions & 135 deletions chromedriver.log

This file was deleted.

13 changes: 13 additions & 0 deletions license.txt
@@ -0,0 +1,13 @@
Copyright 2011 Joshua Arnold, Jeremy Miller

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
2 changes: 1 addition & 1 deletion rakefile.rb
Expand Up @@ -13,7 +13,7 @@
props = { :stage => File.expand_path("build"), :artifacts => File.expand_path("artifacts") }

desc "**Default**"
task :default => [:restore_if_missing, :open_jasmine]
task :default => [:restore_if_missing, :run_jasmine]

desc "Opens the Serenity Jasmine Runner in interactive mode"
task :open_jasmine => [:enable_jasmine_coffee] do
Expand Down
63 changes: 63 additions & 0 deletions readme.md
@@ -0,0 +1,63 @@
# jQuery.continutions

## Overview

jQuery.continuations provides a standarized way of processing Ajax responses via [the Continuation object](https://github.com/DarthFubuMVC/jquery-continuations/wiki/Continuation-object). The idea is that for most cases,
your server side code will be generated responses that are similar in structure and you want to build a conventional approach to processing those requests.

## How it works

jQuery.continuations hooks into jQuery via the $.ajaxSetup method and provides a global success callback. The callback that is registered kicks off the
$.continuations.process pipeline.

## Processing pipeline

The processing pipeline is orchestrated through [continuation policies](https://github.com/DarthFubuMVC/jquery-continuations/wiki/Continuation-policy). jQuery.continuations comes with several policies that are registered by default:

**errorPolicy**

(_Matches when the error collection is not empty_)

Publishes 'ContinuationError' topic through amplifyjs

**refreshPolicy**

(_Matches when the refresh property is true_)

Simply refreshes the page

**navigatePolicy**

(_Matches when the url property is not empty_)

Navigates the window to the specified url

**payloadPolicy**

(_Matches when the following properties exist: payload, topic_)

Publishes the specified topic and payload through amplifyjs

## Request Correlation

Before each request is initiated, a custom header is appended (X-Correlation-Id). This value originates from one of two sources: 1) randomly assigned for a request 2) the id of the form responsible for the request.

> Note: It's up to your web framework to handle setting the header into its response.
Assuming that you are sending the header back down through your response, jquery.continuations handles it from there by doing two things:

**The AjaxCompleted topic**

This topic is published through the jquery.continuations event aggregator facade (we use amplify). The message that is published contains a correlationId property with the appropriate value.

**The continuation processing pipeline**

Before the continuation is processed, the correlationId property is set.

> jQuery.continuations also integrates with jquery.form by providing a correlatedSubmit method to any form ($('#myForm').correlatedSubmit())
## Custom Policies

An example of how to register a custom policy:

> $.continuations.applyPolicy({ custom policy... })
45 changes: 44 additions & 1 deletion src/jquery.continuations/content/scripts/jquery.continuations.js
@@ -1,4 +1,4 @@
// jquery.continuations v0.4.9
// jquery.continuations v0.5.10
//
// Copyright (C)2011 Joshua Arnold, Jeremy Miller
// Distributed Under Apache License, Version 2.0
Expand Down Expand Up @@ -51,6 +51,18 @@
$.continuations.windowService.navigateTo(continuation.navigatePage);
};
};

var redirectPolicy = function () {
this.matches = function (continuation) {
// TODO -- Harden this against the proper statuses
return continuation.matchOnProperty('statusCode', function(c) { return c != 200; })
&& continuation.matchOnProperty('response', function(r) { return r.getResponseHeader('Location'); });
};
this.execute = function (continuation) {
var url = continuation.response.getResponseHeader('Location');
$.continuations.windowService.navigateTo(url);
};
};

var errorPolicy = function () {
this.matches = function (continuation) {
Expand All @@ -60,6 +72,15 @@
$.continuations.trigger('ContinuationError', continuation);
};
};

var httpErrorPolicy = function () {
this.matches = function (continuation) {
return continuation.matchOnProperty('statusCode', function(code) { return code != 200; });
};
this.execute = function (continuation) {
$.continuations.trigger('HttpError', continuation);
};
};

var continuations = function () {
this.callbacks = {};
Expand Down Expand Up @@ -110,6 +131,9 @@
response: jqXHR
});
},
error: function(xhr, text, error) {
self.onError(xhr, text, error);
},
beforeSend: function (xhr, settings) {
self.setupRequest(xhr, settings);
}
Expand All @@ -120,7 +144,26 @@
setupDefaults: function () {
this.applyPolicy(new refreshPolicy());
this.applyPolicy(new navigatePolicy());
this.applyPolicy(new redirectPolicy());
this.applyPolicy(new errorPolicy());
this.applyPolicy(new httpErrorPolicy());
},
onError: function(xhr, text, error) {
var continuation = this.buildError(xhr, text, error);
this.process(continuation);
},
buildError: function(response, text, error) {
var continuation = new $.continuations.continuation();
continuation.success = false;

if (response.getResponseHeader('Content-Type').indexOf('json') != -1) {
continuation = JSON.parse(response.responseText);
}

continuation.response = response;
continuation.statusCode = response.status;

return continuation;
},
onSuccess: function (msg) {
var contentType = msg.response.getResponseHeader('Content-Type');
Expand Down

0 comments on commit 9f6e008

Please sign in to comment.