@@ -88,100 +88,35 @@ function safePropIterator(props, object, max) {
8888}
8989
9090function propIterator ( props , object , max ) {
91- let isInterestingProp = ( type , value ) => {
92- // Do not pick objects, it could cause recursion.
93- return ( type == "boolean" || type == "number" || ( type == "string" && value ) ) ;
94- } ;
95-
9691 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=945377
9792 if ( Object . prototype . toString . call ( object ) === "[object Generator]" ) {
9893 object = Object . getPrototypeOf ( object ) ;
9994 }
10095
101- // Object members with non-empty values are preferred since it gives the
102- // user a better overview of the object.
103- let interestingObject = getFilteredObject ( object , max , isInterestingProp ) ;
104-
105- if ( Object . keys ( interestingObject ) . length < max ) {
106- // There are not enough props yet (or at least, not enough props to
107- // be able to know whether we should print "more…" or not).
108- // Let's display also empty members and functions.
109- interestingObject = Object . assign ( { } , interestingObject ,
110- getFilteredObject (
111- object ,
112- max - Object . keys ( interestingObject ) . length ,
113- ( type , value ) => ! isInterestingProp ( type , value )
114- )
115- ) ;
116- }
117-
118- let propsArray = getPropsArray ( interestingObject , props ) ;
119- if ( Object . keys ( object ) . length > max ) {
120- propsArray . push ( span ( {
121- className : "more-ellipsis" ,
122- title : "more…"
123- } , "…" ) ) ;
124- }
125-
126- return unfoldProps ( propsArray ) ;
127- }
128-
129- function unfoldProps ( items ) {
130- return items . reduce ( ( res , item , index ) => {
131- if ( Array . isArray ( item ) ) {
132- res = res . concat ( item ) ;
133- } else {
134- res . push ( item ) ;
135- }
136-
137- // Interleave commas between elements
138- if ( index !== items . length - 1 ) {
139- res . push ( ", " ) ;
96+ const elements = [ ] ;
97+ const unimportantProperties = [ ] ;
98+ let propertiesNumber = 0 ;
99+ const propertiesNames = Object . keys ( object ) ;
100+
101+ const pushPropRep = ( name , value ) => {
102+ elements . push ( PropRep ( Object . assign ( { } , props , {
103+ key : name ,
104+ mode : MODE . TINY ,
105+ name,
106+ object : value ,
107+ equal : ": " ,
108+ } ) ) ) ;
109+ propertiesNumber ++ ;
110+
111+ if ( propertiesNumber < propertiesNames . length ) {
112+ elements . push ( ", " ) ;
140113 }
141- return res ;
142- } , [ ] ) ;
143- }
144-
145- /**
146- * Get an array of components representing the properties of the object
147- *
148- * @param {Object } object
149- * @param {Object } props
150- * @return {Array } Array of PropRep.
151- */
152- function getPropsArray ( object , props ) {
153- let propsArray = [ ] ;
154-
155- if ( ! object ) {
156- return propsArray ;
157- }
158-
159- // Hardcode tiny mode to avoid recursive handling.
160- let mode = MODE . TINY ;
161- const objectKeys = Object . keys ( object ) ;
162- return objectKeys . map ( ( name , i ) => PropRep ( Object . assign ( { } , props , {
163- mode,
164- name,
165- object : object [ name ] ,
166- equal : ": " ,
167- } ) ) ) ;
168- }
169-
170- /**
171- * Get a copy of the object filtered by a given predicate.
172- *
173- * @param {Object } object.
174- * @param {Number } max The maximum length of keys array.
175- * @param {Function } filter Filter the props you want.
176- * @return {Object } the filtered object.
177- */
178- function getFilteredObject ( object , max , filter ) {
179- let filteredObject = { } ;
114+ } ;
180115
181116 try {
182- for ( let name in object ) {
183- if ( Object . keys ( filteredObject ) . length >= max ) {
184- return filteredObject ;
117+ for ( let name of propertiesNames ) {
118+ if ( propertiesNumber >= max ) {
119+ break ;
185120 }
186121
187122 let value ;
@@ -191,15 +126,50 @@ function getFilteredObject(object, max, filter) {
191126 continue ;
192127 }
193128
194- let t = typeof value ;
195- if ( filter ( t , value ) ) {
196- filteredObject [ name ] = value ;
129+ // Object members with non-empty values are preferred since it gives the
130+ // user a better overview of the object.
131+ if ( isInterestingProp ( value ) ) {
132+ pushPropRep ( name , value ) ;
133+ } else {
134+ // If the property is not important, put its name on an array for later use.
135+ unimportantProperties . push ( name ) ;
197136 }
198137 }
199138 } catch ( err ) {
200139 console . error ( err ) ;
201140 }
202- return filteredObject ;
141+
142+ if ( propertiesNumber < max ) {
143+ for ( let name of unimportantProperties ) {
144+ if ( propertiesNumber >= max ) {
145+ break ;
146+ }
147+
148+ let value ;
149+ try {
150+ value = object [ name ] ;
151+ } catch ( exc ) {
152+ continue ;
153+ }
154+
155+ pushPropRep ( name , value ) ;
156+ }
157+ }
158+
159+ if ( propertiesNumber < propertiesNames . length ) {
160+ elements . push ( span ( {
161+ key : "more" ,
162+ className : "more-ellipsis" ,
163+ title : ", more…"
164+ } , "…" ) ) ;
165+ }
166+
167+ return elements ;
168+ }
169+
170+ function isInterestingProp ( value ) {
171+ const type = typeof value ;
172+ return ( type == "boolean" || type == "number" || ( type == "string" && value ) ) ;
203173}
204174
205175function supportsObject ( object ) {
0 commit comments