|
675 | 675 | //: |
676 | 676 |
|
677 | 677 |
|
678 | | - function formatConsoleArgs(args) { |
| 678 | + function format(args){ |
| 679 | + |
| 680 | + if (typeof args[0] !== "string") return args; |
| 681 | + |
| 682 | + let fmt = args[0]; |
| 683 | + let out = []; |
| 684 | + let argIndex = 1; |
| 685 | + |
| 686 | + out.push(fmt.replace(/%[sdifoO]/g, (match) => { |
| 687 | + |
| 688 | + const val = args[argIndex++]; |
| 689 | + switch (match) { |
| 690 | + case "%s": return ''+val; |
| 691 | + case "%d": |
| 692 | + case "%i": return parseInt(val, 10); |
| 693 | + case "%f": return parseFloat(val); |
| 694 | + case "%o": |
| 695 | + case "%O": return format.fn(val); |
| 696 | + default: |
| 697 | + return match; |
| 698 | + } |
| 699 | + |
| 700 | + })); |
| 701 | + |
| 702 | + // Append any remaining args |
| 703 | + while (argIndex < args.length) { |
| 704 | + out.push(args[argIndex++]); |
| 705 | + } |
| 706 | + |
| 707 | + return out; |
| 708 | + |
| 709 | + |
| 710 | + function fn(val){ |
| 711 | + |
| 712 | + if(val===null)return 'null'; |
| 713 | + if(val===undefined)return 'undefined'; |
| 714 | + |
| 715 | + switch(typeof val){ |
| 716 | + |
| 717 | + case 'number' : return val; |
| 718 | + case 'string' : return val; |
| 719 | + |
| 720 | + }//switch |
| 721 | + |
| 722 | + return JSON.stringify(val,null,2); |
| 723 | + }//fn |
| 724 | + |
| 725 | + }//format |
679 | 726 |
|
680 | | - if (typeof args[0] !== "string") return args; |
681 | | - |
682 | | - let fmt = args[0]; |
683 | | - let out = []; |
684 | | - let argIndex = 1; |
685 | | - |
686 | | - out.push(fmt.replace(/%[sdifoO]/g, (match) => { |
687 | | - const val = args[argIndex++]; |
688 | | - switch (match) { |
689 | | - case "%s": return ''+val; |
690 | | - case "%d": |
691 | | - case "%i": return parseInt(val, 10); |
692 | | - case "%f": return parseFloat(val); |
693 | | - case "%o": |
694 | | - case "%O": |
695 | | - return JSON.stringify(val, null, 2); // or your own inspector |
696 | | - default: |
697 | | - return match; |
698 | | - } |
699 | | - })); |
700 | | - |
701 | | - // Append any remaining args |
702 | | - while (argIndex < args.length) { |
703 | | - out.push(args[argIndex++]); |
704 | | - } |
705 | | - |
706 | | - return out; |
707 | | - |
| 727 | + |
| 728 | + format.fn = function(val,seen=new WeakSet()){ |
| 729 | + |
| 730 | + if (val === null) return 'null'; |
| 731 | + if (val === undefined) return 'undefined'; |
| 732 | + |
| 733 | + // Prevent circular references |
| 734 | + if (typeof val === 'object' || typeof val === 'function') { |
| 735 | + if (seen.has(val)) return '[Circular]'; |
| 736 | + seen.add(val); |
| 737 | + } |
| 738 | + |
| 739 | + // Primitive types |
| 740 | + switch (typeof val) { |
| 741 | + |
| 742 | + case 'number': return String(val); |
| 743 | + case 'string': return `"${val}"`; |
| 744 | + case 'boolean': return String(val); |
| 745 | + case 'bigint': return val.toString() + 'n'; |
| 746 | + case 'symbol': return val.toString(); |
| 747 | + case 'function': return `[Function${val.name ? ': ' + val.name : ''}]`; |
| 748 | + |
| 749 | + }//switch |
| 750 | + |
| 751 | + // Arrays |
| 752 | + if (Array.isArray(val)) { |
| 753 | + return '[' + val.map(v => fn(v, seen)).join(', ') + ']'; |
| 754 | + } |
| 755 | + |
| 756 | + // Date |
| 757 | + if (val instanceof Date) { |
| 758 | + return `Date("${val.toISOString()}")`; |
| 759 | + } |
| 760 | + |
| 761 | + // RegExp |
| 762 | + if (val instanceof RegExp) { |
| 763 | + return val.toString(); |
| 764 | + } |
| 765 | + |
| 766 | + // Error objects |
| 767 | + if (val instanceof Error) { |
| 768 | + return `${val.name}: ${val.message}`; |
| 769 | + } |
| 770 | + |
| 771 | + // Map |
| 772 | + if (val instanceof Map) { |
| 773 | + const entries = []; |
| 774 | + for (const [k, v] of val.entries()) { |
| 775 | + entries.push(`${fn(k, seen)} => ${fn(v, seen)}`); |
| 776 | + } |
| 777 | + return `Map { ${entries.join(', ')} }`; |
| 778 | + } |
| 779 | + |
| 780 | + // Set |
| 781 | + if (val instanceof Set) { |
| 782 | + const entries = [...val].map(v => fn(v, seen)); |
| 783 | + return `Set { ${entries.join(', ')} }`; |
| 784 | + } |
| 785 | + |
| 786 | + // Typed arrays |
| 787 | + if (ArrayBuffer.isView(val) && !(val instanceof DataView)) { |
| 788 | + return `${val.constructor.name} [ ${Array.from(val).join(', ')} ]`; |
| 789 | + } |
| 790 | + |
| 791 | + // DOM nodes |
| 792 | + if (val instanceof Node) { |
| 793 | + if (val.nodeType === 1) { |
| 794 | + return `<${val.tagName.toLowerCase()}>`; |
| 795 | + } |
| 796 | + return val.toString(); |
| 797 | + } |
| 798 | + |
| 799 | + if (typeof val === 'object') { |
| 800 | + const entries = Object.entries(val).map(([k, v]) => { |
| 801 | + |
| 802 | + return `${k}: ${fn(v, seen)}`; |
| 803 | + |
| 804 | + }); |
| 805 | + return `{ ${entries.join(', ')} }`; |
| 806 | + } |
| 807 | + |
| 808 | + try { |
| 809 | + |
| 810 | + return JSON.stringify(val); |
| 811 | + |
| 812 | + }//try |
| 813 | + catch { |
| 814 | + |
| 815 | + return String(val); |
| 816 | + |
| 817 | + }//catch |
| 818 | + |
708 | 819 | } |
709 | 820 |
|
710 | 821 |
|
| 822 | + |
711 | 823 | function build(args){ |
712 | 824 |
|
713 | 825 | var str = ''; |
|
0 commit comments