@@ -184,6 +184,17 @@ function onParseHashComplete(flags, protocol, username, password,
184184 }
185185}
186186
187+ function getEligibleConstructor ( obj ) {
188+ while ( obj !== null ) {
189+ if ( Object . prototype . hasOwnProperty . call ( obj , 'constructor' ) &&
190+ typeof obj . constructor === 'function' ) {
191+ return obj . constructor ;
192+ }
193+ obj = Object . getPrototypeOf ( obj ) ;
194+ }
195+ return null ;
196+ }
197+
187198class URL {
188199 constructor ( input , base ) {
189200 // toUSVString is not needed.
@@ -204,33 +215,43 @@ class URL {
204215 }
205216
206217 [ util . inspect . custom ] ( depth , opts ) {
218+ if ( this == null ||
219+ Object . getPrototypeOf ( this [ context ] ) !== URLContext . prototype ) {
220+ throw new TypeError ( 'Value of `this` is not a URL' ) ;
221+ }
222+
207223 const ctx = this [ context ] ;
208- var ret = 'URL {\n' ;
209- ret += ` href: ${ this . href } \n` ;
210- if ( ctx . scheme !== undefined )
211- ret += ` protocol: ${ this . protocol } \n` ;
212- if ( ctx . username !== undefined )
213- ret += ` username: ${ this . username } \n` ;
214- if ( ctx . password !== undefined ) {
215- const pwd = opts . showHidden ? ctx . password : '--------' ;
216- ret += ` password: ${ pwd } \n` ;
217- }
218- if ( ctx . host !== undefined )
219- ret += ` hostname: ${ this . hostname } \n` ;
220- if ( ctx . port !== undefined )
221- ret += ` port: ${ this . port } \n` ;
222- if ( ctx . path !== undefined )
223- ret += ` pathname: ${ this . pathname } \n` ;
224- if ( ctx . query !== undefined )
225- ret += ` search: ${ this . search } \n` ;
226- if ( ctx . fragment !== undefined )
227- ret += ` hash: ${ this . hash } \n` ;
224+
225+ if ( typeof depth === 'number' && depth < 0 )
226+ return opts . stylize ( '[Object]' , 'special' ) ;
227+
228+ const ctor = getEligibleConstructor ( this ) ;
229+
230+ const obj = Object . create ( {
231+ constructor : ctor === null ? URL : ctor
232+ } ) ;
233+
234+ obj . href = this . href ;
235+ obj . origin = this . origin ;
236+ obj . protocol = this . protocol ;
237+ obj . username = this . username ;
238+ obj . password = ( opts . showHidden || ctx . password == null ) ?
239+ this . password : '--------' ;
240+ obj . host = this . host ;
241+ obj . hostname = this . hostname ;
242+ obj . port = this . port ;
243+ obj . pathname = this . pathname ;
244+ obj . search = this . search ;
245+ obj . searchParams = this . searchParams ;
246+ obj . hash = this . hash ;
247+
228248 if ( opts . showHidden ) {
229- ret += ` cannot-be-base: ${ this [ cannotBeBase ] } \n` ;
230- ret += ` special: ${ this [ special ] } \n` ;
249+ obj . cannotBeBase = this [ cannotBeBase ] ;
250+ obj . special = this [ special ] ;
251+ obj [ context ] = this [ context ] ;
231252 }
232- ret += '}' ;
233- return ret ;
253+
254+ return util . inspect ( obj , opts ) ;
234255 }
235256}
236257
@@ -858,6 +879,9 @@ class URLSearchParams {
858879 throw new TypeError ( 'Value of `this` is not a URLSearchParams' ) ;
859880 }
860881
882+ if ( typeof recurseTimes === 'number' && recurseTimes < 0 )
883+ return ctx . stylize ( '[Object]' , 'special' ) ;
884+
861885 const separator = ', ' ;
862886 const innerOpts = Object . assign ( { } , ctx ) ;
863887 if ( recurseTimes !== null ) {
@@ -1211,6 +1235,12 @@ defineIDLClass(URLSearchParamsIteratorPrototype, 'URLSearchParamsIterator', {
12111235 } ;
12121236 } ,
12131237 [ util . inspect . custom ] ( recurseTimes , ctx ) {
1238+ if ( this == null || this [ context ] == null || this [ context ] . target == null )
1239+ throw new TypeError ( 'Value of `this` is not a URLSearchParamsIterator' ) ;
1240+
1241+ if ( typeof recurseTimes === 'number' && recurseTimes < 0 )
1242+ return ctx . stylize ( '[Object]' , 'special' ) ;
1243+
12141244 const innerOpts = Object . assign ( { } , ctx ) ;
12151245 if ( recurseTimes !== null ) {
12161246 innerOpts . depth = recurseTimes - 1 ;
0 commit comments