utils.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. export function createValueSpan() {
  2. const span = document.createElement( 'span' );
  3. span.className = 'value';
  4. return span;
  5. }
  6. export function setText( element, text ) {
  7. if ( element && element.textContent !== text ) {
  8. element.textContent = text;
  9. }
  10. }
  11. export function getText( element ) {
  12. return element ? element.textContent : null;
  13. }
  14. export function splitPath( fullPath ) {
  15. const lastSlash = fullPath.lastIndexOf( '/' );
  16. if ( lastSlash === - 1 ) {
  17. return {
  18. path: '',
  19. name: fullPath.trim()
  20. };
  21. }
  22. const path = fullPath.substring( 0, lastSlash ).trim();
  23. const name = fullPath.substring( lastSlash + 1 ).trim();
  24. return { path, name };
  25. }
  26. export function splitCamelCase( str ) {
  27. return str.replace( /([a-z0-9])([A-Z])/g, '$1 $2' ).trim();
  28. }
  29. export function formatBytes( bytes, decimals = 2 ) {
  30. if ( bytes === 0 ) return '0 Bytes';
  31. const k = 1024;
  32. const dm = decimals < 0 ? 0 : decimals;
  33. const sizes = [ 'Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' ];
  34. const i = Math.floor( Math.log( bytes ) / Math.log( k ) );
  35. return parseFloat( ( bytes / Math.pow( k, i ) ).toFixed( dm ) ) + ' ' + sizes[ i ];
  36. }
  37. export function info( parentNode, text ) {
  38. let infoIcon = parentNode.querySelector( '.info-icon' );
  39. if ( ! infoIcon ) {
  40. infoIcon = document.createElement( 'span' );
  41. infoIcon.className = 'info-icon';
  42. infoIcon.textContent = 'i';
  43. parentNode.appendChild( infoIcon );
  44. } else {
  45. const newInfoIcon = infoIcon.cloneNode( true );
  46. infoIcon.replaceWith( newInfoIcon );
  47. infoIcon = newInfoIcon;
  48. }
  49. const showTooltip = () => {
  50. const container = infoIcon.closest( '.three-inspector' ) || document.body;
  51. let tooltip = container.querySelector( '.three-inspector-info-tooltip' );
  52. if ( ! tooltip ) {
  53. tooltip = document.createElement( 'div' );
  54. tooltip.className = 'info-tooltip three-inspector-info-tooltip';
  55. container.appendChild( tooltip );
  56. }
  57. const html = text.trim().replace( /### (.*?)(?:\r?\n|$)/g, '<h3>$1</h3>' )
  58. .replace( /\*\*(.*?)\*\*/g, '<strong>$1</strong>' )
  59. .replace( /\n/g, '<br/>' );
  60. tooltip.innerHTML = html;
  61. const rect = infoIcon.getBoundingClientRect();
  62. tooltip.style.left = ( rect.left + rect.width / 2 ) + 'px';
  63. tooltip.style.top = ( rect.top - 8 ) + 'px';
  64. tooltip.style.opacity = '1';
  65. tooltip.style.visibility = 'visible';
  66. };
  67. const hideTooltip = () => {
  68. const container = infoIcon.closest( '.three-inspector' ) || document.body;
  69. const tooltip = container.querySelector( '.three-inspector-info-tooltip' );
  70. if ( tooltip ) {
  71. tooltip.style.opacity = '0';
  72. tooltip.style.visibility = 'hidden';
  73. }
  74. };
  75. infoIcon.addEventListener( 'mouseenter', showTooltip );
  76. infoIcon.addEventListener( 'mouseleave', hideTooltip );
  77. infoIcon.addEventListener( 'click', ( e ) => {
  78. e.stopPropagation();
  79. const container = infoIcon.closest( '.three-inspector' ) || document.body;
  80. const tooltip = container.querySelector( '.three-inspector-info-tooltip' );
  81. if ( tooltip && tooltip.style.visibility === 'visible' ) {
  82. hideTooltip();
  83. } else {
  84. showTooltip();
  85. }
  86. } );
  87. return infoIcon;
  88. }
粤ICP备19079148号