Skip to content

Commit

Permalink
Merge pull request #24 from movableink/kf/fetch-clean
Browse files Browse the repository at this point in the history
Uses `fetch` instead of XMLHttpRequest in CD.get
  • Loading branch information
istateside authored Jan 22, 2018
2 parents 5d65e95 + 11ea0fd commit c2aa50c
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 153 deletions.
18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,20 @@ if (customerQuality === 'very-good') {
CD.pause(tenSeconds, 'making bad customers wait for their email to load...');

setTimeout(() => {
target.innerText = 'bad customers have to wait for their images';
CD.resume();
target.innerText = 'bad customers have to wait for their images';
}, 1000);
}
```

It is generally recommended to call CD.pause as the last thing before starting
an asynchronous action, and CD.resume as the very first thing once that action
has finished. If your asynchronous action completes successfully, but your
callback runs some code before calling CD.resume again, then you run the risk of
triggering a JavaScript error that stops execution of the current script. If
CD.resume is not called after that first CD.pause, your image will eventually
time out, as opposed to failing immediately.

*NOTE:* Cropduster previously offered `CD.suspend` and `CD.capture` functions
that achieved a similar goal. These functions have been replaced with `pause`
and `resume`, to support a better synchronisation of state with Capturama, and
Expand Down Expand Up @@ -212,9 +220,8 @@ console.log('If user clicks on the web crop, they will go to http://example.com'

## Testing

brew install phantomjs
npm install
npm test
yarn install
yarn run test

## Publishing

Expand All @@ -229,6 +236,9 @@ console.log('If user clicks on the web crop, they will go to http://example.com'

## Changelog

### 5.2.0
* CD.get uses the `fetch` API instead of XMLHttpRequest

### 5.1.0
* Add `withoutCredentials` to `CD.get()` options to disable sending `withCredentials` in requests.

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cropduster",
"version": "5.1.0",
"version": "5.2.0",
"description": "Library for building web pages for use with Movable Ink Web Crops",
"main": "src/cropduster.js",
"directories": {
Expand All @@ -11,6 +11,7 @@
"babel-loader": "^7.0.0",
"babel-polyfill": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"fetch-mock": "^6.0.0-beta.7",
"karma": "^1.7.1",
"karma-babel-preprocessor": "^6.0.1",
"karma-chrome-launcher": "^2.2.0",
Expand Down
89 changes: 42 additions & 47 deletions src/cropduster.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,70 +189,49 @@ const CD = {
options = {};
}

const msg = `xhr: ${url}`;
const deprecatedCallback = function() {
if (callback && typeof callback === 'function') {
CD.log(DEPRECATION_MSG);
return callback(...arguments);
}
};

const msg = `xhr: ${url}`;

return new Promise(function(resolve, reject) {
try {
const req = new XMLHttpRequest();
CD.pause(options.maxSuspension || 0, msg);

req.onerror = function() {
const error = `XHR error for ${url} - ${this.status}: ${this.statusText}`;
const requestOptions = CD._optionsForFetch(options);

CD.resume(msg);

deprecatedCallback(null);

reject(new Error(error));
};

req.onload = function() {
const contentType = this.getResponseHeader('content-type');
const data = this.responseText;
const status = this.status;

if (status >= 400) {
return this.onerror();
}
return fetch(url, requestOptions).then(response => {
if (!response.ok) {
throw new Error(response.statusText); // A non-200 range status was returned
}

CD.resume(msg);
return response.text().then(data => {
const status = response.status;
const contentType = response.headers.get('Content-Type');

deprecatedCallback(data, status, contentType);
deprecatedCallback(data, status, contentType);

resolve({
contentType,
data,
status
});
return {
data,
status,
contentType
};
});
}).then(
(response) => {
CD.resume(msg);
return response;
},
(error) => {
CD.log(`Error encountered in CD.get for ${url}: ${error}`);
CD.resume(msg);

req.open(options.method || 'GET', url, true);

req.withCredentials = !options.withoutCredentials;

if (options.headers) {
for (const header in options.headers) {
req.setRequestHeader(header, options.headers[header]);
}
}

req.send(options.body);
CD.pause(options.maxSuspension, msg);
} catch (error) {
deprecatedCallback(null);

reject({
message: `Cropduster failed to create Promise: ${error}`,
error: error
});
throw error;
}
});
);
},

getImage(url, options = {}, callback) {
Expand Down Expand Up @@ -369,6 +348,22 @@ const CD = {
}

return hash.toString();
},

_optionsForFetch(options) {
const requestOptions = {
redirect: 'follow',
headers: new Headers(options.headers || {}),
method: options.method || 'GET',
body: options.body,
mode: 'cors'
};

if (!options.withoutCredentials) {
requestOptions.credentials = 'include';
}

return requestOptions;
}
};

Expand Down
Loading

0 comments on commit c2aa50c

Please sign in to comment.