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

helpers.ts 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /**
  2. * A helper function that behaves similar to Object.assign, but only reassigns a
  3. * property in target if it's defined in source.
  4. *
  5. * @param {Object} target - The target object to assign the values into.
  6. * @param {Object} source - The source object.
  7. * @returns {Object}
  8. */
  9. export function assignIfDefined(target: Object, source: Object) {
  10. const to = Object(target);
  11. for (const nextKey in source) {
  12. if (source.hasOwnProperty(nextKey)) {
  13. const value = source[nextKey as keyof typeof source];
  14. if (typeof value !== 'undefined') {
  15. to[nextKey] = value;
  16. }
  17. }
  18. }
  19. return to;
  20. }
  21. const MATCH_OPERATOR_REGEXP = /[|\\{}()[\]^$+*?.-]/g;
  22. /**
  23. * Escape RegExp special characters.
  24. *
  25. * Based on https://github.com/sindresorhus/escape-string-regexp.
  26. *
  27. * @param {string} s - The regexp string to escape.
  28. * @returns {string}
  29. */
  30. export function escapeRegexp(s: string) {
  31. if (typeof s !== 'string') {
  32. throw new TypeError('Expected a string');
  33. }
  34. return s.replace(MATCH_OPERATOR_REGEXP, '\\$&');
  35. }
  36. /**
  37. * Returns the base URL of the app.
  38. *
  39. * @param {Object} w - Window object to use instead of the built in one.
  40. * @returns {string}
  41. */
  42. export function getBaseUrl(w: typeof window = window) {
  43. const doc = w.document;
  44. const base = doc.querySelector('base');
  45. if (base?.href) {
  46. return base.href;
  47. }
  48. const { protocol, host } = w.location;
  49. return `${protocol}//${host}`;
  50. }
  51. /**
  52. * Returns the namespace for all global variables, functions, etc that we need.
  53. *
  54. * @returns {Object} The namespace.
  55. *
  56. * NOTE: After React-ifying everything this should be the only global.
  57. */
  58. export function getJitsiMeetGlobalNS() {
  59. if (!window.JitsiMeetJS) {
  60. window.JitsiMeetJS = {};
  61. }
  62. if (!window.JitsiMeetJS.app) {
  63. window.JitsiMeetJS.app = {};
  64. }
  65. return window.JitsiMeetJS.app;
  66. }
  67. /**
  68. * Returns the object that stores the connection times.
  69. *
  70. * @returns {Object} - The object that stores the connection times.
  71. */
  72. export function getJitsiMeetGlobalNSConnectionTimes() {
  73. const globalNS = getJitsiMeetGlobalNS();
  74. if (!globalNS.connectionTimes) {
  75. globalNS.connectionTimes = {};
  76. }
  77. return globalNS.connectionTimes;
  78. }
  79. /**
  80. * Prints the error and reports it to the global error handler.
  81. *
  82. * @param {Error} e - The error object.
  83. * @param {string} msg - A custom message to print in addition to the error.
  84. * @returns {void}
  85. */
  86. export function reportError(e: Error, msg = '') {
  87. console.error(msg, e);
  88. window.onerror?.(msg, undefined, undefined, undefined, e);
  89. }
  90. /**
  91. * Adds alpha to a color css string.
  92. *
  93. * @param {string} color - The color string either in rgb... Or #... Format.
  94. * @param {number} opacity -The opacity(alpha) to apply to the color. Can take a value between 0 and 1, including.
  95. * @returns {string} - The color with applied alpha.
  96. */
  97. export function setColorAlpha(color: string, opacity: number) {
  98. if (!color) {
  99. return `rgba(0, 0, 0, ${opacity})`;
  100. }
  101. let b, g, r;
  102. try {
  103. if (color.startsWith('rgb')) {
  104. [ r, g, b ] = color.split('(')[1].split(')')[0].split(',').map(c => c.trim());
  105. } else if (color.startsWith('#')) {
  106. if (color.length === 4) {
  107. [ r, g, b ] = parseShorthandColor(color);
  108. } else {
  109. r = parseInt(color.substring(1, 3), 16);
  110. g = parseInt(color.substring(3, 5), 16);
  111. b = parseInt(color.substring(5, 7), 16);
  112. }
  113. } else {
  114. return color;
  115. }
  116. return `rgba(${r}, ${g}, ${b}, ${opacity})`;
  117. } catch {
  118. return color;
  119. }
  120. }
  121. /**
  122. * Gets the hexa rgb values for a shorthand css color.
  123. *
  124. * @param {string} color - The shorthand css color.
  125. * @returns {Array<number>} - Array containing parsed r, g, b values of the color.
  126. */
  127. function parseShorthandColor(color: string) {
  128. let b, g, r;
  129. r = color.substring(1, 2);
  130. r += r;
  131. r = parseInt(r, 16);
  132. g = color.substring(2, 3);
  133. g += g;
  134. g = parseInt(g, 16);
  135. b = color.substring(3, 4);
  136. b += b;
  137. b = parseInt(b, 16);
  138. return [ r, g, b ];
  139. }
  140. /**
  141. * Sorts an object by a sort function, same functionality as array.sort().
  142. *
  143. * @param {Object} object - The data object.
  144. * @param {Function} callback - The sort function.
  145. * @returns {void}
  146. */
  147. export function objectSort(object: Object, callback: Function) {
  148. return Object.entries(object)
  149. .sort(([ , a ], [ , b ]) => callback(a, b))
  150. .reduce((row, [ key, value ]) => {
  151. return { ...row,
  152. [key]: value };
  153. }, {});
  154. }