Changing XHR to Fetch API

pull/1845/head
Henrique Medeiros 2 years ago
parent 38ea0aae6e
commit 755199a4b1

@ -70,7 +70,7 @@ The app's main goals are to:
The web app is all client-side JavaScript, written in [CoffeeScript](http://coffeescript.org), and powered by a small [Sinatra](http://www.sinatrarb.com)/[Sprockets](https://github.com/rails/sprockets) application. It relies on files generated by the [scraper](#scraper).
Many of the code's design decisions were driven by the fact that the app uses XHR to load content directly into the main frame. This includes stripping the original documents of most of their HTML markup (e.g. scripts and stylesheets) to avoid polluting the main frame, and prefixing all CSS class names with an underscore to prevent conflicts.
Many of the code's design decisions were driven by the fact that the app uses Fetch to load content directly into the main frame. This includes stripping the original documents of most of their HTML markup (e.g. scripts and stylesheets) to avoid polluting the main frame, and prefixing all CSS class names with an underscore to prevent conflicts.
Another driving factor is performance and the fact that everything happens in the browser. A service worker (which comes with its own set of constraints) and `localStorage` are used to speed up the boot time, while memory consumption is kept in check by allowing the user to pick his/her own set of documentations. The search algorithm is kept simple because it needs to be fast even searching through 100,000 strings.

@ -6,18 +6,32 @@ MIME_TYPES =
applyDefaults(options)
serializeData(options)
xhr = new XMLHttpRequest()
xhr.open(options.type, options.url, options.async)
applyCallbacks(xhr, options)
applyHeaders(xhr, options)
xhr.send(options.data)
if options.async
abort: abort.bind(undefined, xhr)
else
parseResponse(xhr, options)
abortController = new AbortController()
timer = setTimeout =>
abortController.abort()
, options.timeout * 1000
fetch(
options.url,
headers: processHeaders(options)
method: options.type
contentType: options.dataType
signal: abortController.signal
).then((response) ->
if options.dataType == 'json'
response.json()
else
response.text()
).then((data) ->
if data?
onSuccess data, options
else
onError 'invalid', '', options
).catch((error) ->
onError 'error', error, options
).finally ->
clearTimeout timer
ajax.defaults =
async: true
@ -51,19 +65,7 @@ serializeData = (options) ->
serializeParams = (params) ->
("#{encodeURIComponent key}=#{encodeURIComponent value}" for key, value of params).join '&'
applyCallbacks = (xhr, options) ->
return unless options.async
xhr.timer = setTimeout onTimeout.bind(undefined, xhr, options), options.timeout * 1000
xhr.onprogress = options.progress if options.progress
xhr.onreadystatechange = ->
if xhr.readyState is 4
clearTimeout(xhr.timer)
onComplete(xhr, options)
return
return
applyHeaders = (xhr, options) ->
processHeaders = (options) ->
options.headers or= {}
if options.contentType
@ -74,45 +76,13 @@ applyHeaders = (xhr, options) ->
if options.dataType
options.headers['Accept'] = MIME_TYPES[options.dataType] or options.dataType
return options.headers
for key, value of options.headers
xhr.setRequestHeader(key, value)
onSuccess = (data, options) ->
options.success?.call options.context, data, options
return
onComplete = (xhr, options) ->
if 200 <= xhr.status < 300
if (response = parseResponse(xhr, options))?
onSuccess response, xhr, options
else
onError 'invalid', xhr, options
else
onError 'error', xhr, options
onError = (type, error, options) ->
options.error?.call options.context, type, error, options
return
onSuccess = (response, xhr, options) ->
options.success?.call options.context, response, xhr, options
return
onError = (type, xhr, options) ->
options.error?.call options.context, type, xhr, options
return
onTimeout = (xhr, options) ->
xhr.abort()
onError 'timeout', xhr, options
return
abort = (xhr) ->
clearTimeout(xhr.timer)
xhr.onreadystatechange = null
xhr.abort()
return
parseResponse = (xhr, options) ->
if options.dataType is 'json'
parseJSON(xhr.responseText)
else
xhr.responseText
parseJSON = (json) ->
try JSON.parse(json) catch

Loading…
Cancel
Save