@@ -625,6 +625,10 @@ function onParseHashComplete(flags, protocol, username, password, |
625 | 625 | this[context].fragment = fragment; |
626 | 626 | } |
627 | 627 |
|
| 628 | +function isURLThis(self) { |
| 629 | + return self?.[context] !== undefined; |
| 630 | +} |
| 631 | + |
628 | 632 | class URL { |
629 | 633 | constructor(input, base) { |
630 | 634 | // toUSVString is not needed. |
@@ -737,14 +741,20 @@ class URL { |
737 | 741 |
|
738 | 742 | // https://heycam.github.io/webidl/#es-stringifier |
739 | 743 | toString() { |
| 744 | + if (!isURLThis(this)) |
| 745 | + throw new ERR_INVALID_THIS('URL'); |
740 | 746 | return this[kFormat]({}); |
741 | 747 | } |
742 | 748 |
|
743 | 749 | get href() { |
| 750 | + if (!isURLThis(this)) |
| 751 | + throw new ERR_INVALID_THIS('URL'); |
744 | 752 | return this[kFormat]({}); |
745 | 753 | } |
746 | 754 |
|
747 | 755 | set href(input) { |
| 756 | + if (!isURLThis(this)) |
| 757 | + throw new ERR_INVALID_THIS('URL'); |
748 | 758 | // toUSVString is not needed. |
749 | 759 | input = `${input}`; |
750 | 760 | parse(input, -1, undefined, undefined, |
@@ -753,6 +763,8 @@ class URL { |
753 | 763 |
|
754 | 764 | // readonly |
755 | 765 | get origin() { |
| 766 | + if (!isURLThis(this)) |
| 767 | + throw new ERR_INVALID_THIS('URL'); |
756 | 768 | // Refs: https://url.spec.whatwg.org/#concept-url-origin |
757 | 769 | const ctx = this[context]; |
758 | 770 | switch (ctx.scheme) { |
@@ -776,10 +788,14 @@ class URL { |
776 | 788 | } |
777 | 789 |
|
778 | 790 | get protocol() { |
| 791 | + if (!isURLThis(this)) |
| 792 | + throw new ERR_INVALID_THIS('URL'); |
779 | 793 | return this[context].scheme; |
780 | 794 | } |
781 | 795 |
|
782 | 796 | set protocol(scheme) { |
| 797 | + if (!isURLThis(this)) |
| 798 | + throw new ERR_INVALID_THIS('URL'); |
783 | 799 | // toUSVString is not needed. |
784 | 800 | scheme = `${scheme}`; |
785 | 801 | if (scheme.length === 0) |
@@ -790,10 +806,14 @@ class URL { |
790 | 806 | } |
791 | 807 |
|
792 | 808 | get username() { |
| 809 | + if (!isURLThis(this)) |
| 810 | + throw new ERR_INVALID_THIS('URL'); |
793 | 811 | return this[context].username; |
794 | 812 | } |
795 | 813 |
|
796 | 814 | set username(username) { |
| 815 | + if (!isURLThis(this)) |
| 816 | + throw new ERR_INVALID_THIS('URL'); |
797 | 817 | // toUSVString is not needed. |
798 | 818 | username = `${username}`; |
799 | 819 | if (this[cannotHaveUsernamePasswordPort]) |
@@ -809,10 +829,14 @@ class URL { |
809 | 829 | } |
810 | 830 |
|
811 | 831 | get password() { |
| 832 | + if (!isURLThis(this)) |
| 833 | + throw new ERR_INVALID_THIS('URL'); |
812 | 834 | return this[context].password; |
813 | 835 | } |
814 | 836 |
|
815 | 837 | set password(password) { |
| 838 | + if (!isURLThis(this)) |
| 839 | + throw new ERR_INVALID_THIS('URL'); |
816 | 840 | // toUSVString is not needed. |
817 | 841 | password = `${password}`; |
818 | 842 | if (this[cannotHaveUsernamePasswordPort]) |
@@ -828,6 +852,8 @@ class URL { |
828 | 852 | } |
829 | 853 |
|
830 | 854 | get host() { |
| 855 | + if (!isURLThis(this)) |
| 856 | + throw new ERR_INVALID_THIS('URL'); |
831 | 857 | const ctx = this[context]; |
832 | 858 | let ret = ctx.host || ''; |
833 | 859 | if (ctx.port !== null) |
@@ -836,6 +862,8 @@ class URL { |
836 | 862 | } |
837 | 863 |
|
838 | 864 | set host(host) { |
| 865 | + if (!isURLThis(this)) |
| 866 | + throw new ERR_INVALID_THIS('URL'); |
839 | 867 | const ctx = this[context]; |
840 | 868 | // toUSVString is not needed. |
841 | 869 | host = `${host}`; |
@@ -848,10 +876,14 @@ class URL { |
848 | 876 | } |
849 | 877 |
|
850 | 878 | get hostname() { |
| 879 | + if (!isURLThis(this)) |
| 880 | + throw new ERR_INVALID_THIS('URL'); |
851 | 881 | return this[context].host || ''; |
852 | 882 | } |
853 | 883 |
|
854 | 884 | set hostname(host) { |
| 885 | + if (!isURLThis(this)) |
| 886 | + throw new ERR_INVALID_THIS('URL'); |
855 | 887 | const ctx = this[context]; |
856 | 888 | // toUSVString is not needed. |
857 | 889 | host = `${host}`; |
@@ -863,11 +895,15 @@ class URL { |
863 | 895 | } |
864 | 896 |
|
865 | 897 | get port() { |
| 898 | + if (!isURLThis(this)) |
| 899 | + throw new ERR_INVALID_THIS('URL'); |
866 | 900 | const port = this[context].port; |
867 | 901 | return port === null ? '' : String(port); |
868 | 902 | } |
869 | 903 |
|
870 | 904 | set port(port) { |
| 905 | + if (!isURLThis(this)) |
| 906 | + throw new ERR_INVALID_THIS('URL'); |
871 | 907 | // toUSVString is not needed. |
872 | 908 | port = `${port}`; |
873 | 909 | if (this[cannotHaveUsernamePasswordPort]) |
@@ -882,6 +918,8 @@ class URL { |
882 | 918 | } |
883 | 919 |
|
884 | 920 | get pathname() { |
| 921 | + if (!isURLThis(this)) |
| 922 | + throw new ERR_INVALID_THIS('URL'); |
885 | 923 | const ctx = this[context]; |
886 | 924 | if (this[cannotBeBase]) |
887 | 925 | return ctx.path[0]; |
@@ -891,6 +929,8 @@ class URL { |
891 | 929 | } |
892 | 930 |
|
893 | 931 | set pathname(path) { |
| 932 | + if (!isURLThis(this)) |
| 933 | + throw new ERR_INVALID_THIS('URL'); |
894 | 934 | // toUSVString is not needed. |
895 | 935 | path = `${path}`; |
896 | 936 | if (this[cannotBeBase]) |
@@ -900,13 +940,17 @@ class URL { |
900 | 940 | } |
901 | 941 |
|
902 | 942 | get search() { |
| 943 | + if (!isURLThis(this)) |
| 944 | + throw new ERR_INVALID_THIS('URL'); |
903 | 945 | const { query } = this[context]; |
904 | 946 | if (query === null || query === '') |
905 | 947 | return ''; |
906 | 948 | return `?${query}`; |
907 | 949 | } |
908 | 950 |
|
909 | 951 | set search(search) { |
| 952 | + if (!isURLThis(this)) |
| 953 | + throw new ERR_INVALID_THIS('URL'); |
910 | 954 | const ctx = this[context]; |
911 | 955 | search = toUSVString(search); |
912 | 956 | if (search === '') { |
@@ -926,17 +970,23 @@ class URL { |
926 | 970 |
|
927 | 971 | // readonly |
928 | 972 | get searchParams() { |
| 973 | + if (!isURLThis(this)) |
| 974 | + throw new ERR_INVALID_THIS('URL'); |
929 | 975 | return this[searchParams]; |
930 | 976 | } |
931 | 977 |
|
932 | 978 | get hash() { |
| 979 | + if (!isURLThis(this)) |
| 980 | + throw new ERR_INVALID_THIS('URL'); |
933 | 981 | const { fragment } = this[context]; |
934 | 982 | if (fragment === null || fragment === '') |
935 | 983 | return ''; |
936 | 984 | return `#${fragment}`; |
937 | 985 | } |
938 | 986 |
|
939 | 987 | set hash(hash) { |
| 988 | + if (!isURLThis(this)) |
| 989 | + throw new ERR_INVALID_THIS('URL'); |
940 | 990 | const ctx = this[context]; |
941 | 991 | // toUSVString is not needed. |
942 | 992 | hash = `${hash}`; |
@@ -953,6 +1003,8 @@ class URL { |
953 | 1003 | } |
954 | 1004 |
|
955 | 1005 | toJSON() { |
| 1006 | + if (!isURLThis(this)) |
| 1007 | + throw new ERR_INVALID_THIS('URL'); |
956 | 1008 | return this[kFormat]({}); |
957 | 1009 | } |
958 | 1010 |
|
|