Skip to content

Commit 834f1e5

Browse files
authored
Merge pull request #51 from github/accept
Allow setting custom Accept header for requests
2 parents 21f70c7 + b028d34 commit 834f1e5

File tree

4 files changed

+116
-8
lines changed

4 files changed

+116
-8
lines changed

include-fragment-element.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ function getData(el) {
3737
}
3838
}
3939

40+
function isWildcard(accept) {
41+
return accept && !!accept.split(',').find(x => x.match(/^\s*\*\/\*/))
42+
}
43+
4044
export default class IncludeFragmentElement extends HTMLElement {
4145
constructor() {
4246
super()
@@ -58,11 +62,15 @@ export default class IncludeFragmentElement extends HTMLElement {
5862
}
5963

6064
set src(val) {
61-
if (val) {
62-
this.setAttribute('src', val)
63-
} else {
64-
this.removeAttribute('src')
65-
}
65+
this.setAttribute('src', val)
66+
}
67+
68+
get accept() {
69+
return this.getAttribute('accept')
70+
}
71+
72+
set accept(val) {
73+
this.setAttribute('accept', val)
6674
}
6775

6876
get data() {
@@ -99,7 +107,7 @@ export default class IncludeFragmentElement extends HTMLElement {
99107
method: 'GET',
100108
credentials: 'same-origin',
101109
headers: {
102-
Accept: 'text/html'
110+
Accept: this.accept || 'text/html'
103111
}
104112
})
105113
}
@@ -115,8 +123,8 @@ export default class IncludeFragmentElement extends HTMLElement {
115123
throw new Error(`Failed to load resource: the server responded with a status of ${response.status}`)
116124
}
117125
const ct = response.headers.get('Content-Type')
118-
if (!ct || !ct.match(/^text\/html/)) {
119-
throw new Error(`Failed to load resource: expected text/html but was ${ct}`)
126+
if (!isWildcard(this.accept) && (!ct || !ct.match(this.accept ? this.accept : /^text\/html/))) {
127+
throw new Error(`Failed to load resource: expected ${this.accept || 'text/html'} but was ${ct}`)
120128
}
121129
return response
122130
})

include-fragment-element.js.flow

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ declare module '@github/include-fragment-element' {
55
get data(): Promise<string>;
66
get src(): string;
77
set src(url: string): void;
8+
get accept(): string;
9+
set accept(accept: string): void;
810
fetch(request: Request): Promise<Response>;
911
}
1012
}

index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export default class IncludeFragmentElement extends HTMLElement {
22
readonly data: Promise<string>;
33
src: string;
4+
accept: string;
45
fetch(request: Request): Promise<Response>;
56
}
67

test/test.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,28 @@ const responses = {
3939
'Content-Type': 'text/html'
4040
}
4141
})
42+
},
43+
'/fragment': function(request) {
44+
if (request.headers.get('Accept') === 'text/html; fragment') {
45+
return new Response('<div id="fragment">fragment</div>', {
46+
status: 200,
47+
headers: {
48+
'Content-Type': 'text/html; fragment'
49+
}
50+
})
51+
} else {
52+
return new Response('406', {
53+
status: 406
54+
})
55+
}
56+
},
57+
'/test.js': function() {
58+
return new Response('alert("what")', {
59+
status: 200,
60+
headers: {
61+
'Content-Type': 'text/javascript'
62+
}
63+
})
4264
}
4365
}
4466

@@ -159,6 +181,49 @@ suite('include-fragment-element', function() {
159181
})
160182
})
161183

184+
test('throws on incorrect Content-Type', function() {
185+
const el = document.createElement('include-fragment')
186+
el.setAttribute('src', '/test.js')
187+
188+
return el.data.then(
189+
() => {
190+
assert.ok(false)
191+
},
192+
error => {
193+
assert.match(error, /expected text\/html but was text\/javascript/)
194+
}
195+
)
196+
})
197+
198+
test('throws on non-matching Content-Type', function() {
199+
const el = document.createElement('include-fragment')
200+
el.setAttribute('accept', 'text/html; fragment')
201+
el.setAttribute('src', '/hello')
202+
203+
return el.data.then(
204+
() => {
205+
assert.ok(false)
206+
},
207+
error => {
208+
assert.match(error, /expected text\/html; fragment but was text\/html; charset=utf-8/)
209+
}
210+
)
211+
})
212+
213+
test('throws on 406', function() {
214+
const el = document.createElement('include-fragment')
215+
el.setAttribute('src', '/fragment')
216+
217+
return el.data.then(
218+
() => {
219+
assert.ok(false)
220+
},
221+
error => {
222+
assert.match(error, /the server responded with a status of 406/)
223+
}
224+
)
225+
})
226+
162227
test('data is not writable', function() {
163228
const el = document.createElement('include-fragment')
164229
assert.ok(el.data !== 42)
@@ -231,6 +296,28 @@ suite('include-fragment-element', function() {
231296
})
232297
})
233298

299+
test('replaces with response with accept header for any', function() {
300+
const div = document.createElement('div')
301+
div.innerHTML = '<include-fragment src="/test.js" accept="*/*">loading</include-fragment>'
302+
document.body.appendChild(div)
303+
304+
return when(div.firstChild, 'load').then(() => {
305+
assert.equal(document.querySelector('include-fragment'), null)
306+
assert.match(document.body.textContent, /alert\("what"\)/)
307+
})
308+
})
309+
310+
test('replaces with response with the right accept header', function() {
311+
const div = document.createElement('div')
312+
div.innerHTML = '<include-fragment src="/fragment" accept="text/html; fragment">loading</include-fragment>'
313+
document.body.appendChild(div)
314+
315+
return when(div.firstChild, 'load').then(() => {
316+
assert.equal(document.querySelector('include-fragment'), null)
317+
assert.equal(document.querySelector('#fragment').textContent, 'fragment')
318+
})
319+
})
320+
234321
test('error event is not cancelable or bubbles', function() {
235322
const div = document.createElement('div')
236323
div.innerHTML = '<include-fragment src="/boom">loading</include-fragment>'
@@ -262,6 +349,16 @@ suite('include-fragment-element', function() {
262349
)
263350
})
264351

352+
test('adds is-error class on incorrect Content-Type', function() {
353+
const div = document.createElement('div')
354+
div.innerHTML = '<include-fragment src="/fragment">loading</include-fragment>'
355+
document.body.appendChild(div)
356+
357+
return when(div.firstChild, 'error').then(() =>
358+
assert.ok(document.querySelector('include-fragment').classList.contains('is-error'))
359+
)
360+
})
361+
265362
test('replaces element when src attribute is changed', function() {
266363
const elem = document.createElement('include-fragment')
267364
document.body.appendChild(elem)

0 commit comments

Comments
 (0)