您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

helpers.js 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // @flow
  2. /**
  3. * A helper function that behaves similar to Object.assign, but only reassigns a
  4. * property in target if it's defined in source.
  5. *
  6. * @param {Object} target - The target object to assign the values into.
  7. * @param {Object} source - The source object.
  8. * @returns {Object}
  9. */
  10. export function assignIfDefined(target: Object, source: Object) {
  11. const to = Object(target);
  12. for (const nextKey in source) {
  13. if (source.hasOwnProperty(nextKey)) {
  14. const value = source[nextKey];
  15. if (typeof value !== 'undefined') {
  16. to[nextKey] = value;
  17. }
  18. }
  19. }
  20. return to;
  21. }
  22. /**
  23. * Tries to copy a given text to the clipboard.
  24. * Returns true if the action succeeds.
  25. *
  26. * @param {string} textToCopy - Text to be copied.
  27. * @returns {Promise<boolean>}
  28. */
  29. export async function copyText(textToCopy: string) {
  30. try {
  31. await navigator.clipboard.writeText(textToCopy);
  32. return true;
  33. } catch (clipboardAPIError) { // The Clipboard API is not supported.
  34. let fakeTextArea = document.createElement('textarea');
  35. // $FlowFixMe
  36. fakeTextArea = document.body.appendChild(fakeTextArea);
  37. fakeTextArea.value = textToCopy;
  38. fakeTextArea.focus();
  39. fakeTextArea.select();
  40. let result;
  41. try {
  42. result = document.execCommand('copy');
  43. } catch (error) {
  44. result = false;
  45. }
  46. // $FlowFixMe
  47. document.body.removeChild(fakeTextArea);
  48. return result;
  49. }
  50. }
  51. /**
  52. * Creates a deferred object.
  53. *
  54. * @returns {{promise, resolve, reject}}
  55. */
  56. export function createDeferred(): Object {
  57. const deferred = {};
  58. deferred.promise = new Promise((resolve, reject) => {
  59. deferred.resolve = resolve;
  60. deferred.reject = reject;
  61. });
  62. return deferred;
  63. }
  64. const MATCH_OPERATOR_REGEXP = /[|\\{}()[\]^$+*?.-]/g;
  65. /**
  66. * Escape RegExp special characters.
  67. *
  68. * Based on https://github.com/sindresorhus/escape-string-regexp.
  69. *
  70. * @param {string} s - The regexp string to escape.
  71. * @returns {string}
  72. */
  73. export function escapeRegexp(s: string) {
  74. if (typeof s !== 'string') {
  75. throw new TypeError('Expected a string');
  76. }
  77. return s.replace(MATCH_OPERATOR_REGEXP, '\\$&');
  78. }
  79. /**
  80. * Returns the base URL of the app.
  81. *
  82. * @param {Object} w - Window object to use instead of the built in one.
  83. * @returns {string}
  84. */
  85. export function getBaseUrl(w: Object = window) {
  86. const doc = w.document;
  87. const base = doc.querySelector('base');
  88. if (base && base.href) {
  89. return base.href;
  90. }
  91. const { protocol, host } = w.location;
  92. return `${protocol}//${host}`;
  93. }
  94. /**
  95. * Returns the namespace for all global variables, functions, etc that we need.
  96. *
  97. * @returns {Object} The namespace.
  98. *
  99. * NOTE: After React-ifying everything this should be the only global.
  100. */
  101. export function getJitsiMeetGlobalNS() {
  102. if (!window.JitsiMeetJS) {
  103. window.JitsiMeetJS = {};
  104. }
  105. if (!window.JitsiMeetJS.app) {
  106. window.JitsiMeetJS.app = {};
  107. }
  108. return window.JitsiMeetJS.app;
  109. }
  110. /**
  111. * Prints the error and reports it to the global error handler.
  112. *
  113. * @param {Error} e - The error object.
  114. * @param {string} msg - A custom message to print in addition to the error.
  115. * @returns {void}
  116. */
  117. export function reportError(e: Object, msg: string = '') {
  118. console.error(msg, e);
  119. window.onerror && window.onerror(msg, null, null, null, e);
  120. }