diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-06-13 10:23:04 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-13 10:23:04 -0400 | 
| commit | 8a7ff6a18c78bbc2048dd4017597ccc4f5ee4106 (patch) | |
| tree | 58333fc1a5a3da13180e8d0bbd5e65d79b34fa27 | |
| parent | 5cba421201b596f4430dd45f3715ad515661b109 (diff) | |
Replace XMLHttpRequest (#562)
* Replace XMLHttpRequest with fetch
* Implement fetch placeholder for tests
| -rw-r--r-- | ext/bg/js/audio-uri-builder.js | 41 | ||||
| -rw-r--r-- | ext/bg/js/request.js | 42 | ||||
| -rw-r--r-- | ext/mixed/js/audio-system.js | 30 | ||||
| -rw-r--r-- | test/test-database.js | 66 | 
4 files changed, 73 insertions, 106 deletions
| diff --git a/ext/bg/js/audio-uri-builder.js b/ext/bg/js/audio-uri-builder.js index 27e97680..7dd5e4c6 100644 --- a/ext/bg/js/audio-uri-builder.js +++ b/ext/bg/js/audio-uri-builder.js @@ -82,16 +82,24 @@ class AudioUriBuilder {      }      async _getUriJpod101Alternate(definition) { -        const response = await new Promise((resolve, reject) => { -            const xhr = new XMLHttpRequest(); -            xhr.open('POST', 'https://www.japanesepod101.com/learningcenter/reference/dictionary_post'); -            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); -            xhr.addEventListener('error', () => reject(new Error('Failed to scrape audio data'))); -            xhr.addEventListener('load', () => resolve(xhr.responseText)); -            xhr.send(`post=dictionary_reference&match_type=exact&search_query=${encodeURIComponent(definition.expression)}`); +        const fetchUrl = 'https://www.japanesepod101.com/learningcenter/reference/dictionary_post'; +        const data = `post=dictionary_reference&match_type=exact&search_query=${encodeURIComponent(definition.expression)}`; +        const response = await fetch(fetchUrl, { +            method: 'POST', +            mode: 'no-cors', +            cache: 'default', +            credentials: 'omit', +            redirect: 'follow', +            referrerPolicy: 'no-referrer', +            headers: { +                'Content-Type': 'application/x-www-form-urlencoded' +            }, +            body: data          }); +        const responseText = await response.text(); +        console.log(responseText); -        const dom = new DOMParser().parseFromString(response, 'text/html'); +        const dom = new DOMParser().parseFromString(responseText, 'text/html');          for (const row of dom.getElementsByClassName('dc-result-row')) {              try {                  const url = row.querySelector('audio>source[src]').getAttribute('src'); @@ -108,15 +116,18 @@ class AudioUriBuilder {      }      async _getUriJisho(definition) { -        const response = await new Promise((resolve, reject) => { -            const xhr = new XMLHttpRequest(); -            xhr.open('GET', `https://jisho.org/search/${definition.expression}`); -            xhr.addEventListener('error', () => reject(new Error('Failed to scrape audio data'))); -            xhr.addEventListener('load', () => resolve(xhr.responseText)); -            xhr.send(); +        const fetchUrl = `https://jisho.org/search/${definition.expression}`; +        const response = await fetch(fetchUrl, { +            method: 'GET', +            mode: 'no-cors', +            cache: 'default', +            credentials: 'omit', +            redirect: 'follow', +            referrerPolicy: 'no-referrer'          }); +        const responseText = await response.text(); -        const dom = new DOMParser().parseFromString(response, 'text/html'); +        const dom = new DOMParser().parseFromString(responseText, 'text/html');          try {              const audio = dom.getElementById(`audio_${definition.expression}:${definition.reading}`);              if (audio !== null) { diff --git a/ext/bg/js/request.js b/ext/bg/js/request.js index 957ac0f5..d1c6ed4e 100644 --- a/ext/bg/js/request.js +++ b/ext/bg/js/request.js @@ -16,28 +16,28 @@   */ -function requestText(url, action, params) { -    return new Promise((resolve, reject) => { -        const xhr = new XMLHttpRequest(); -        xhr.overrideMimeType('text/plain'); -        xhr.addEventListener('load', () => resolve(xhr.responseText)); -        xhr.addEventListener('error', () => reject(new Error('Failed to connect'))); -        xhr.open(action, url); -        if (params) { -            xhr.send(JSON.stringify(params)); -        } else { -            xhr.send(); -        } +async function requestText(url, method, data) { +    const response = await fetch(url, { +        method, +        mode: 'no-cors', +        cache: 'default', +        credentials: 'omit', +        redirect: 'follow', +        referrerPolicy: 'no-referrer', +        body: (data ? JSON.stringify(data) : void 0)      }); +    return await response.text();  } -async function requestJson(url, action, params) { -    const responseText = await requestText(url, action, params); -    try { -        return JSON.parse(responseText); -    } catch (e) { -        const error = new Error(`Invalid response (${e.message || e})`); -        error.data = {url, action, params, responseText}; -        throw error; -    } +async function requestJson(url, method, data) { +    const response = await fetch(url, { +        method, +        mode: 'no-cors', +        cache: 'default', +        credentials: 'omit', +        redirect: 'follow', +        referrerPolicy: 'no-referrer', +        body: (data ? JSON.stringify(data) : void 0) +    }); +    return await response.json();  } diff --git a/ext/mixed/js/audio-system.js b/ext/mixed/js/audio-system.js index fdfb0b10..c590b909 100644 --- a/ext/mixed/js/audio-system.js +++ b/ext/mixed/js/audio-system.js @@ -169,22 +169,22 @@ class AudioSystem {          });      } -    _createAudioBinaryFromUrl(url) { -        return new Promise((resolve, reject) => { -            const xhr = new XMLHttpRequest(); -            xhr.responseType = 'arraybuffer'; -            xhr.addEventListener('load', async () => { -                const arrayBuffer = xhr.response; -                if (!await this._isAudioBinaryValid(arrayBuffer)) { -                    reject(new Error('Could not retrieve audio')); -                } else { -                    resolve(arrayBuffer); -                } -            }); -            xhr.addEventListener('error', () => reject(new Error('Failed to connect'))); -            xhr.open('GET', url); -            xhr.send(); +    async _createAudioBinaryFromUrl(url) { +        const response = await fetch(url, { +            method: 'GET', +            mode: 'no-cors', +            cache: 'default', +            credentials: 'omit', +            redirect: 'follow', +            referrerPolicy: 'no-referrer'          }); +        const arrayBuffer = await response.arrayBuffer(); + +        if (!await this._isAudioBinaryValid(arrayBuffer)) { +            throw new Error('Could not retrieve audio'); +        } + +        return arrayBuffer;      }      _isAudioValid(audio) { diff --git a/test/test-database.js b/test/test-database.js index e8a4a343..63989857 100644 --- a/test/test-database.js +++ b/test/test-database.js @@ -38,60 +38,6 @@ const chrome = {      }  }; -class XMLHttpRequest { -    constructor() { -        this._eventCallbacks = new Map(); -        this._url = ''; -        this._responseText = null; -    } - -    overrideMimeType() { -        // NOP -    } - -    addEventListener(eventName, callback) { -        let callbacks = this._eventCallbacks.get(eventName); -        if (typeof callbacks === 'undefined') { -            callbacks = []; -            this._eventCallbacks.set(eventName, callbacks); -        } -        callbacks.push(callback); -    } - -    open(action, url2) { -        this._url = url2; -    } - -    send() { -        const filePath = url.fileURLToPath(this._url); -        Promise.resolve() -            .then(() => { -                let source; -                try { -                    source = fs.readFileSync(filePath, {encoding: 'utf8'}); -                } catch (e) { -                    this._trigger('error'); -                    return; -                } -                this._responseText = source; -                this._trigger('load'); -            }); -    } - -    get responseText() { -        return this._responseText; -    } - -    _trigger(eventName, ...args) { -        const callbacks = this._eventCallbacks.get(eventName); -        if (typeof callbacks === 'undefined') { return; } - -        for (let i = 0, ii = callbacks.length; i < ii; ++i) { -            callbacks[i](...args); -        } -    } -} -  class Image {      constructor() {          this._src = ''; @@ -138,11 +84,21 @@ class Image {      }  } +async function fetch(url2) { +    const filePath = url.fileURLToPath(url2); +    await Promise.resolve(); +    const content = fs.readFileSync(filePath, {encoding: null}); +    return { +        text: async () => Promise.resolve(content.toString('utf8')), +        json: async () => Promise.resolve(JSON.parse(content.toString('utf8'))) +    }; +} +  const vm = new VM({      chrome,      Image, -    XMLHttpRequest, +    fetch,      indexedDB: global.indexedDB,      IDBKeyRange: global.IDBKeyRange,      JSZip: yomichanTest.JSZip, |