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.web.js 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /**
  2. * Loads a script from a specific source. This is an extended version of
  3. * loadScript method from ScriptUtil in lib-jitsi-meet.
  4. *
  5. * @param {string} src - The source from the which the script is to be
  6. * (down)loaded. Can be absolute or relative URL.
  7. * @param {Object} options - Additional options.
  8. * @param {boolean} options.async=true - True to asynchronously load the script
  9. * or false to synchronously load the script.
  10. * @param {boolean} options.prepend=false - True to schedule the loading of the
  11. * script as soon as possible or false to schedule the loading of the script at
  12. * the end of the scripts known at the time.
  13. * @returns {void}
  14. */
  15. export function loadScript(
  16. src,
  17. options = {
  18. async: true,
  19. prepend: false
  20. }) {
  21. return new Promise((resolve, reject) => {
  22. const d = document;
  23. const tagName = 'script';
  24. const script = d.createElement(tagName);
  25. const referenceNode = d.getElementsByTagName(tagName)[0];
  26. let scriptSource = src;
  27. if (isRelativeURL(src)) {
  28. // Find the src URL of the current loaded script and use it as the
  29. // base of the specified src (argument).
  30. const scriptEl = document.currentScript;
  31. if (scriptEl) {
  32. const scriptSrc = scriptEl.src;
  33. const baseScriptSrc
  34. = scriptSrc.substring(0, scriptSrc.lastIndexOf('/') + 1);
  35. if (scriptSrc && baseScriptSrc) {
  36. scriptSource = new URL(src, baseScriptSrc).toString();
  37. }
  38. }
  39. }
  40. script.async = Boolean(options.async);
  41. script.onerror = reject;
  42. script.onload = resolve;
  43. script.src = scriptSource;
  44. if (referenceNode) {
  45. if (options.prepend) {
  46. referenceNode.parentNode.insertBefore(script, referenceNode);
  47. } else {
  48. referenceNode.parentNode.appendChild(script);
  49. }
  50. } else {
  51. const head = d.getElementsByTagName('head')[0];
  52. head.appendChild(script);
  53. }
  54. });
  55. }
  56. /**
  57. * Determines if passed URL is relative or not.
  58. *
  59. * @param {string} url - URL.
  60. * @returns {boolean}
  61. */
  62. function isRelativeURL(url) {
  63. let relative;
  64. // XXX If the specified value is an absolute URL, then an URL object will be
  65. // correctly initialized from it. Otherwise, an exception will be thrown and
  66. // we will treat the specified value as a relative URL.
  67. try {
  68. new URL(url); // eslint-disable-line no-new
  69. relative = false;
  70. } catch (ex) {
  71. relative = true;
  72. }
  73. return relative;
  74. }