You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

loadScript.native.js 1.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. /**
  2. * Loads a script from a specific source. React Native cannot load a JS
  3. * file/resource/URL via a <script> HTML element, so the implementation
  4. * fetches the specified src as plain text (e.g. via XMLHttpRequest) and then
  5. * evaluates the fetched string as JavaScript code (i.e. via the {@link eval}
  6. * function).
  7. *
  8. * @param {string} src - The source from the which the script is to be
  9. * (down)loaded. Only absolute URLs are supported.
  10. * @param {Object} options - Additional options.
  11. * @param {boolean} options.async=true - True to asynchronously load the script
  12. * or false to synchronously load the script.
  13. * @returns {void}
  14. */
  15. export function loadScript(
  16. src,
  17. options = {
  18. async: true
  19. }) {
  20. return new Promise((resolve, reject) => {
  21. // XXX We are using XMLHttpRequest instead of Fetch API only in order
  22. // to be able to do 'sync' requests. If this not needed, this can be
  23. // replaced with much simpler and readable fetch().
  24. const xhr = new XMLHttpRequest();
  25. xhr.open('GET', src, options.async);
  26. xhr.responseType = 'text';
  27. xhr.onload = () => {
  28. if (xhr.readyState === 4) {
  29. if (xhr.status === 200) {
  30. try {
  31. // eslint-disable-next-line no-eval
  32. eval.call(window, xhr.responseText);
  33. resolve();
  34. } catch (e) {
  35. reject(e);
  36. }
  37. } else {
  38. reject(xhr.statusText);
  39. }
  40. }
  41. };
  42. xhr.onerror = () => reject(xhr.statusText);
  43. xhr.send();
  44. });
  45. }