From edb7c7336f53b5c0e08ef0ccb37e43c8d9de778f Mon Sep 17 00:00:00 2001 From: David Graham Date: Sat, 12 Mar 2016 09:47:14 -0700 Subject: [PATCH 1/5] Fix formatting --- fetch.js | 12 ++++++------ test/test.js | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/fetch.js b/fetch.js index 788da78c..33222809 100644 --- a/fetch.js +++ b/fetch.js @@ -110,7 +110,7 @@ var support = { blob: 'FileReader' in self && 'Blob' in self && (function() { try { - new Blob(); + new Blob() return true } catch(e) { return false @@ -320,9 +320,9 @@ return new Response(null, {status: status, headers: {location: url}}) } - self.Headers = Headers; - self.Request = Request; - self.Response = Response; + self.Headers = Headers + self.Request = Request + self.Response = Response self.fetch = function(input, init) { return new Promise(function(resolve, reject) { @@ -345,7 +345,7 @@ return xhr.getResponseHeader('X-Request-URL') } - return; + return } xhr.onload = function() { @@ -355,7 +355,7 @@ headers: headers(xhr), url: responseURL() } - var body = 'response' in xhr ? xhr.response : xhr.responseText; + var body = 'response' in xhr ? xhr.response : xhr.responseText resolve(new Response(body, options)) } diff --git a/test/test.js b/test/test.js index a402c93e..08d21734 100644 --- a/test/test.js +++ b/test/test.js @@ -185,7 +185,7 @@ suite('Headers', function() { test('converts field value to string on set and get', function() { var headers = new Headers() headers.set('Content-Type', 1) - headers.set('X-CSRF-Token', undefined); + headers.set('X-CSRF-Token', undefined) assert.equal(headers.get('Content-Type'), '1') assert.equal(headers.get('X-CSRF-Token'), 'undefined') }) @@ -193,8 +193,8 @@ suite('Headers', function() { assert.throws(function() { new Headers({'': ['application/json']}) }, TypeError) assert.throws(function() { new Headers({'Accept:': ['application/json']}) }, TypeError) assert.throws(function() { - var headers = new Headers(); - headers.set({field: 'value'}, 'application/json'); + var headers = new Headers() + headers.set({field: 'value'}, 'application/json') }, TypeError) }) featureDependent(test, !nativeFirefox, 'is iterable with forEach', function() { @@ -527,11 +527,11 @@ suite('Response', function() { }) test('creates Headers object from raw headers', function() { - var r = new Response('{"foo":"bar"}', {headers: {'content-type': 'application/json'}}); - assert.equal(r.headers instanceof Headers, true); + var r = new Response('{"foo":"bar"}', {headers: {'content-type': 'application/json'}}) + assert.equal(r.headers instanceof Headers, true) return r.json().then(function(json){ - assert.equal(json.foo, 'bar'); - return json; + assert.equal(json.foo, 'bar') + return json }) }) @@ -574,7 +574,7 @@ suite('Response', function() { test('redirect creates redirect Response', function() { var r = Response.redirect('https://fetch.spec.whatwg.org/', 301) - assert(r instanceof Response); + assert(r instanceof Response) assert.equal(r.status, 301) assert.equal(r.headers.get('Location'), 'https://fetch.spec.whatwg.org/') }) @@ -949,7 +949,7 @@ suite('Atomic HTTP redirect handling', function() { // https://fetch.spec.whatwg.org/#concept-request-credentials-mode suite('credentials mode', function() { setup(function() { - return fetch('/cookie?name=foo&value=reset', {credentials: 'same-origin'}); + return fetch('/cookie?name=foo&value=reset', {credentials: 'same-origin'}) }) featureDependent(suite, exerciseMode === 'native', 'omit', function() { @@ -960,7 +960,7 @@ suite('credentials mode', function() { test('does not accept cookies with implicit omit credentials', function() { return fetch('/cookie?name=foo&value=bar').then(function() { - return fetch('/cookie?name=foo', {credentials: 'same-origin'}); + return fetch('/cookie?name=foo', {credentials: 'same-origin'}) }).then(function(response) { return response.text() }).then(function(data) { @@ -970,7 +970,7 @@ suite('credentials mode', function() { test('does not accept cookies with omit credentials', function() { return fetch('/cookie?name=foo&value=bar', {credentials: 'omit'}).then(function() { - return fetch('/cookie?name=foo', {credentials: 'same-origin'}); + return fetch('/cookie?name=foo', {credentials: 'same-origin'}) }).then(function(response) { return response.text() }).then(function(data) { @@ -980,7 +980,7 @@ suite('credentials mode', function() { test('does not send cookies with implicit omit credentials', function() { return fetch('/cookie?name=foo&value=bar', {credentials: 'same-origin'}).then(function() { - return fetch('/cookie?name=foo'); + return fetch('/cookie?name=foo') }).then(function(response) { return response.text() }).then(function(data) { From 3ebc7ed0b4c87cfcc8f3a4d30822f882a1731516 Mon Sep 17 00:00:00 2001 From: David Graham Date: Sat, 12 Mar 2016 09:48:13 -0700 Subject: [PATCH 2/5] Add Headers#keys iterator --- fetch.js | 11 +++++++++++ test/test.js | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/fetch.js b/fetch.js index 33222809..a7c0c484 100644 --- a/fetch.js +++ b/fetch.js @@ -77,6 +77,17 @@ }, this) } + Headers.prototype.keys = function() { + var items = [] + this.forEach(function(value, name) { items.push(name) }) + return { + next: function() { + var value = items.shift() + return {done: value === undefined, value: value} + } + } + } + function consumed(body) { if (body.bodyUsed) { return Promise.reject(new TypeError('Already read')) diff --git a/test/test.js b/test/test.js index 08d21734..4dbb7cd2 100644 --- a/test/test.js +++ b/test/test.js @@ -220,6 +220,18 @@ suite('Headers', function() { assert.equal(this, thisArg) }, thisArg) }) + test('is iterable with keys', function() { + var headers = new Headers() + headers.append('Accept', 'application/json') + headers.append('Accept', 'text/plain') + headers.append('Content-Type', 'text/html') + + var iterator = headers.keys() + assert.deepEqual({done: false, value: 'accept'}, iterator.next()) + assert.deepEqual({done: false, value: 'accept'}, iterator.next()) + assert.deepEqual({done: false, value: 'content-type'}, iterator.next()) + assert.deepEqual({done: true, value: undefined}, iterator.next()) + }) }) // https://fetch.spec.whatwg.org/#request-class From 6f7a588fd0bbc1eb8e5e77a349f10497a1a0c217 Mon Sep 17 00:00:00 2001 From: David Graham Date: Sat, 12 Mar 2016 09:53:57 -0700 Subject: [PATCH 3/5] Add Headers#values iterator --- fetch.js | 11 +++++++++++ test/test.js | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/fetch.js b/fetch.js index a7c0c484..1551d654 100644 --- a/fetch.js +++ b/fetch.js @@ -88,6 +88,17 @@ } } + Headers.prototype.values = function() { + var items = [] + this.forEach(function(value) { items.push(value) }) + return { + next: function() { + var value = items.shift() + return {done: value === undefined, value: value} + } + } + } + function consumed(body) { if (body.bodyUsed) { return Promise.reject(new TypeError('Already read')) diff --git a/test/test.js b/test/test.js index 4dbb7cd2..9e54aa97 100644 --- a/test/test.js +++ b/test/test.js @@ -232,6 +232,18 @@ suite('Headers', function() { assert.deepEqual({done: false, value: 'content-type'}, iterator.next()) assert.deepEqual({done: true, value: undefined}, iterator.next()) }) + test('is iterable with values', function() { + var headers = new Headers() + headers.append('Accept', 'application/json') + headers.append('Accept', 'text/plain') + headers.append('Content-Type', 'text/html') + + var iterator = headers.values() + assert.deepEqual({done: false, value: 'application/json'}, iterator.next()) + assert.deepEqual({done: false, value: 'text/plain'}, iterator.next()) + assert.deepEqual({done: false, value: 'text/html'}, iterator.next()) + assert.deepEqual({done: true, value: undefined}, iterator.next()) + }) }) // https://fetch.spec.whatwg.org/#request-class From 12e692e7c9e36b5d4ad7b2928ab8d75441e6e879 Mon Sep 17 00:00:00 2001 From: David Graham Date: Sat, 12 Mar 2016 09:58:02 -0700 Subject: [PATCH 4/5] Add Headers#entries iterator --- fetch.js | 11 +++++++++++ test/test.js | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/fetch.js b/fetch.js index 1551d654..dea9c30b 100644 --- a/fetch.js +++ b/fetch.js @@ -99,6 +99,17 @@ } } + Headers.prototype.entries = function() { + var items = [] + this.forEach(function(value, name) { items.push([name, value]) }) + return { + next: function() { + var value = items.shift() + return {done: value === undefined, value: value} + } + } + } + function consumed(body) { if (body.bodyUsed) { return Promise.reject(new TypeError('Already read')) diff --git a/test/test.js b/test/test.js index 9e54aa97..e800108f 100644 --- a/test/test.js +++ b/test/test.js @@ -244,6 +244,18 @@ suite('Headers', function() { assert.deepEqual({done: false, value: 'text/html'}, iterator.next()) assert.deepEqual({done: true, value: undefined}, iterator.next()) }) + test('is iterable with entries', function() { + var headers = new Headers() + headers.append('Accept', 'application/json') + headers.append('Accept', 'text/plain') + headers.append('Content-Type', 'text/html') + + var iterator = headers.entries() + assert.deepEqual({done: false, value: ['accept', 'application/json']}, iterator.next()) + assert.deepEqual({done: false, value: ['accept', 'text/plain']}, iterator.next()) + assert.deepEqual({done: false, value: ['content-type', 'text/html']}, iterator.next()) + assert.deepEqual({done: true, value: undefined}, iterator.next()) + }) }) // https://fetch.spec.whatwg.org/#request-class From a1b7674b6942d4265ea47b74760a486b2bf5e3da Mon Sep 17 00:00:00 2001 From: David Graham Date: Sat, 12 Mar 2016 10:47:06 -0700 Subject: [PATCH 5/5] Make Headers iterable if Symbol is available --- fetch.js | 62 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/fetch.js b/fetch.js index dea9c30b..f3412dc4 100644 --- a/fetch.js +++ b/fetch.js @@ -5,6 +5,20 @@ return } + var support = { + iterable: 'Symbol' in self && 'iterator' in Symbol, + blob: 'FileReader' in self && 'Blob' in self && (function() { + try { + new Blob() + return true + } catch(e) { + return false + } + })(), + formData: 'FormData' in self, + arrayBuffer: 'ArrayBuffer' in self + } + function normalizeName(name) { if (typeof name !== 'string') { name = String(name) @@ -80,34 +94,62 @@ Headers.prototype.keys = function() { var items = [] this.forEach(function(value, name) { items.push(name) }) - return { + var iterator = { next: function() { var value = items.shift() return {done: value === undefined, value: value} } } + + if (support.iterable) { + iterator[Symbol.iterator] = function() { + return iterator + } + } + + return iterator } Headers.prototype.values = function() { var items = [] this.forEach(function(value) { items.push(value) }) - return { + var iterator = { next: function() { var value = items.shift() return {done: value === undefined, value: value} } } + + if (support.iterable) { + iterator[Symbol.iterator] = function() { + return iterator + } + } + + return iterator } Headers.prototype.entries = function() { var items = [] this.forEach(function(value, name) { items.push([name, value]) }) - return { + var iterator = { next: function() { var value = items.shift() return {done: value === undefined, value: value} } } + + if (support.iterable) { + iterator[Symbol.iterator] = function() { + return iterator + } + } + + return iterator + } + + if (support.iterable) { + Headers.prototype[Symbol.iterator] = Headers.prototype.entries } function consumed(body) { @@ -140,23 +182,9 @@ return fileReaderReady(reader) } - var support = { - blob: 'FileReader' in self && 'Blob' in self && (function() { - try { - new Blob() - return true - } catch(e) { - return false - } - })(), - formData: 'FormData' in self, - arrayBuffer: 'ArrayBuffer' in self - } - function Body() { this.bodyUsed = false - this._initBody = function(body) { this._bodyInit = body if (typeof body === 'string') {