@@ -16,12 +16,13 @@ import * as TextUtils from '../../models/text_utils/text_utils.js';
1616import * as Buttons from '../../ui/components/buttons/buttons.js' ;
1717import * as SourceFrame from '../../ui/legacy/components/source_frame/source_frame.js' ;
1818import * as UI from '../../ui/legacy/legacy.js' ;
19- import { html , render } from '../../ui/lit/lit.js' ;
19+ import { Directives , html , render } from '../../ui/lit/lit.js' ;
2020import * as VisualLogging from '../../ui/visual_logging/visual_logging.js' ;
2121
2222import { type Command , Events as JSONEditorEvents , JSONEditor , type Parameter } from './JSONEditor.js' ;
2323import protocolMonitorStyles from './protocolMonitor.css.js' ;
2424
25+ const { styleMap} = Directives ;
2526const { widgetConfig} = UI . Widget ;
2627const UIStrings = {
2728 /**
@@ -176,15 +177,21 @@ export interface ProtocolDomain {
176177export interface ViewInput {
177178 messages : Message [ ] ;
178179 selectedMessage ?: Message ;
179- filters : TextUtils . TextUtils . ParsedFilter [ ] ;
180+ hideInputBar : boolean ;
181+ command : string ;
182+ commandSuggestions : string [ ] ;
183+ filterKeys : string [ ] ;
184+ filter : string ;
185+ parseFilter : ( filter : string ) => TextUtils . TextUtils . ParsedFilter [ ] ;
180186 onRecord : ( e : Event ) => void ;
181187 onClear : ( ) => void ;
182188 onSave : ( ) => void ;
183189 onSelect : ( e : CustomEvent < HTMLElement | null > ) => void ;
184190 onContextMenu : ( e : CustomEvent < { menu : UI . ContextMenu . ContextMenu , element : HTMLElement } > ) => void ;
185- textFilterUI : UI . Toolbar . ToolbarInput ;
191+ onFilterChanged : ( e : CustomEvent < string > ) => void ;
192+ onCommandChange : ( e : CustomEvent < string > ) => void ;
193+ onCommandSubmitted : ( e : CustomEvent < string > ) => void ;
186194 showHideSidebarButton : UI . Toolbar . ToolbarButton ;
187- commandInput : UI . Toolbar . ToolbarInput ;
188195 selector : UI . Toolbar . ToolbarComboBox ;
189196}
190197
@@ -198,17 +205,17 @@ export class ProtocolMonitorDataGrid extends Common.ObjectWrapper.eventMixin<Eve
198205 private startTime : number ;
199206 private readonly messageForId = new Map < number , Message > ( ) ;
200207 private readonly filterParser : TextUtils . TextUtils . FilterParser ;
201- private readonly suggestionBuilder : UI . FilterSuggestionBuilder . FilterSuggestionBuilder ;
202- private readonly textFilterUI : UI . Toolbar . ToolbarInput ;
208+ #filterKeys = [ 'method' , 'request' , 'response' , 'target' , 'session' ] ;
203209 readonly selector : UI . Toolbar . ToolbarComboBox ;
204210 #commandAutocompleteSuggestionProvider = new CommandAutocompleteSuggestionProvider ( ) ;
205211 #selectedTargetId?: string ;
206- #commandInput: UI . Toolbar . ToolbarInput ;
212+ #command = '' ;
213+ #hideInputBar = false ;
207214 #showHideSidebarButton: UI . Toolbar . ToolbarButton ;
208215 #view: View ;
209216 #messages: Message [ ] = [ ] ;
210217 #selectedMessage: Message | undefined ;
211- #filters: TextUtils . TextUtils . ParsedFilter [ ] = [ ] ;
218+ #filter = '' ;
212219 #splitWidget: UI . SplitWidget . SplitWidget ;
213220 constructor ( splitWidget : UI . SplitWidget . SplitWidget , view : View = ( input , output , target ) => {
214221 // clang-format off
@@ -233,7 +240,17 @@ export class ProtocolMonitorDataGrid extends Common.ObjectWrapper.eventMixin<Eve
233240 .variant=${ Buttons . Button . Variant . TOOLBAR }
234241 .jslogContext=${ 'protocol-monitor.save' }
235242 @click=${ input . onSave } > </ devtools-button >
236- ${ input . textFilterUI . element }
243+ < devtools-toolbar-input type ="filter "
244+ list ="filter-suggestions "
245+ style ="flex-grow: 1 "
246+ value =${ input . filter }
247+ @change =${ input . onFilterChanged } >
248+ < datalist id ="filter-suggestions ">
249+ ${ input . filterKeys . map ( key => html `
250+ < option value =${ key + ':' } > </ option >
251+ < option value =${ '-' + key + ':' } > </ option > ` ) }
252+ </ datalist >
253+ </ devtools-toolbar-input >
237254 </ devtools-toolbar >
238255 < devtools-split-widget .options =${ {
239256 vertical : true ,
@@ -245,7 +262,7 @@ export class ProtocolMonitorDataGrid extends Common.ObjectWrapper.eventMixin<Eve
245262 slot ="main "
246263 @select =${ input . onSelect }
247264 @contextmenu =${ input . onContextMenu }
248- .filters=${ input . filters } >
265+ .filters=${ input . parseFilter ( input . filter ) } >
249266 < table >
250267 < tr >
251268 < th id ="type " sortable style ="text-align: center " hideable weight ="1 "> ${ i18nString ( UIStrings . type ) } </ th >
@@ -302,7 +319,20 @@ export class ProtocolMonitorDataGrid extends Common.ObjectWrapper.eventMixin<Eve
302319 < devtools-toolbar class ="protocol-monitor-bottom-toolbar "
303320 jslog =${ VisualLogging . toolbar ( 'bottom' ) } >
304321 ${ input . showHideSidebarButton . element }
305- ${ input . commandInput . element }
322+ < devtools-toolbar-input id ="command-input "
323+ style =${ styleMap ( {
324+ 'flex-grow' : 1 ,
325+ display : input . hideInputBar ? 'none' : 'flex' } ) }
326+ value =${ input . command }
327+ list="command-input-suggestions"
328+ placeholder=${ i18nString ( UIStrings . sendRawCDPCommand ) }
329+ title=${ i18nString ( UIStrings . sendRawCDPCommandExplanation ) }
330+ @change=${ input . onCommandChange }
331+ @submit=${ input . onCommandSubmitted } >
332+ < datalist id ="command-input-suggestions ">
333+ ${ input . commandSuggestions . map ( c => html `< option value =${ c } > </ option > ` ) }
334+ </ datalist >
335+ </ devtools-toolbar-input >
306336 ${ input . selector . element }
307337 </ devtools-toolbar > ` ,
308338 target ,
@@ -318,23 +348,13 @@ export class ProtocolMonitorDataGrid extends Common.ObjectWrapper.eventMixin<Eve
318348 this . contentElement . classList . add ( 'protocol-monitor' ) ;
319349 this . selector = this . #createTargetSelector( ) ;
320350
321- const keys = [ 'method' , 'request' , 'response' , 'type' , 'target' , 'session' ] ;
322- this . filterParser = new TextUtils . TextUtils . FilterParser ( keys ) ;
323- this . suggestionBuilder = new UI . FilterSuggestionBuilder . FilterSuggestionBuilder ( keys ) ;
351+ this . #filterKeys = [ 'method' , 'request' , 'response' , 'type' , 'target' , 'session' ] ;
352+ this . filterParser = new TextUtils . TextUtils . FilterParser ( this . #filterKeys) ;
324353
325- this . textFilterUI = new UI . Toolbar . ToolbarFilter (
326- undefined , 1 , .2 , '' , this . suggestionBuilder . completions . bind ( this . suggestionBuilder ) , true ) ;
327- this . textFilterUI . addEventListener ( UI . Toolbar . ToolbarInput . Event . TEXT_CHANGED , event => {
328- const query = event . data ;
329- this . #filters = this . filterParser . parse ( query ) ;
330- this . requestUpdate ( ) ;
331- } ) ;
332354 this . #showHideSidebarButton = splitWidget . createShowHideSidebarButton (
333355 i18nString ( UIStrings . showCDPCommandEditor ) , i18nString ( UIStrings . hideCDPCommandEditor ) ,
334356 i18nString ( UIStrings . CDPCommandEditorShown ) , i18nString ( UIStrings . CDPCommandEditorHidden ) ,
335357 'protocol-monitor.toggle-command-editor' ) ;
336- this . #commandInput = this . #createCommandInput( ) ;
337- const inputBar = this . #commandInput. element ;
338358 const tabSelector = this . selector . element ;
339359
340360 const populateToolbarInput = ( ) : void => {
@@ -352,24 +372,25 @@ export class ProtocolMonitorDataGrid extends Common.ObjectWrapper.eventMixin<Eve
352372 }
353373 }
354374 if ( commandJson ) {
355- this . #commandInput. setValue ( commandJson ) ;
375+ this . #command = commandJson ;
376+ this . requestUpdate ( ) ;
356377 }
357378 } ;
358379
359380 splitWidget . addEventListener ( UI . SplitWidget . Events . SHOW_MODE_CHANGED , ( event => {
360381 if ( event . data === 'OnlyMain' ) {
361382 populateToolbarInput ( ) ;
362-
363- inputBar ?. setAttribute ( 'style' , 'display:flex; flex-grow: 1' ) ;
383+ this . #hideInputBar = false ;
364384 tabSelector ?. setAttribute ( 'style' , 'display:flex' ) ;
365385 } else {
366- const { command, parameters} = parseCommandInput ( this . #commandInput . value ( ) ) ;
386+ const { command, parameters} = parseCommandInput ( this . #command ) ;
367387 this . dispatchEventToListeners (
368388 Events . COMMAND_CHANGE ,
369389 { command, parameters, targetId : this . #selectedTargetId} ) ;
370- inputBar ?. setAttribute ( 'style' , 'display:none' ) ;
390+ this . #hideInputBar = true ;
371391 tabSelector ?. setAttribute ( 'style' , 'display:none' ) ;
372392 }
393+ this . requestUpdate ( ) ;
373394 } ) ) ;
374395 this . performUpdate ( ) ;
375396 }
@@ -378,7 +399,12 @@ export class ProtocolMonitorDataGrid extends Common.ObjectWrapper.eventMixin<Eve
378399 const viewInput = {
379400 messages : this . #messages,
380401 selectedMessage : this . #selectedMessage,
381- filters : this . #filters,
402+ hideInputBar : this . #hideInputBar,
403+ command : this . #command,
404+ commandSuggestions : this . #commandAutocompleteSuggestionProvider. allSuggestions ( ) ,
405+ filterKeys : this . #filterKeys,
406+ filter : this . #filter,
407+ parseFilter : this . filterParser . parse . bind ( this . filterParser ) ,
382408 onRecord : ( e : Event ) => {
383409 this . setRecording ( ( e . target as Buttons . Button . Button ) . toggled ) ;
384410 } ,
@@ -401,9 +427,19 @@ export class ProtocolMonitorDataGrid extends Common.ObjectWrapper.eventMixin<Eve
401427 this . #populateContextMenu( e . detail . menu , message ) ;
402428 }
403429 } ,
404- textFilterUI : this . textFilterUI ,
430+ onCommandChange : ( e : CustomEvent < string > ) => {
431+ this . #command = e . detail ;
432+ } ,
433+ onCommandSubmitted : ( e : CustomEvent < string > ) => {
434+ this . #commandAutocompleteSuggestionProvider. addEntry ( e . detail ) ;
435+ const { command, parameters} = parseCommandInput ( e . detail ) ;
436+ this . onCommandSend ( command , parameters , this . #selectedTargetId) ;
437+ } ,
438+ onFilterChanged : ( e : CustomEvent < string > ) => {
439+ this . #filter = e . detail ;
440+ this . requestUpdate ( ) ;
441+ } ,
405442 showHideSidebarButton : this . #showHideSidebarButton,
406- commandInput : this . #commandInput,
407443 selector : this . selector ,
408444 } ;
409445 const viewOutput = { } ;
@@ -434,7 +470,8 @@ export class ProtocolMonitorDataGrid extends Common.ObjectWrapper.eventMixin<Eve
434470 * current row.
435471 */
436472 menu . editSection ( ) . appendItem ( i18nString ( UIStrings . filter ) , ( ) => {
437- this . textFilterUI . setValue ( `method:${ message . method } ` , true ) ;
473+ this . #filter = `method:${ message . method } ` ;
474+ this . requestUpdate ( ) ;
438475 } , { jslogContext : 'filter' } ) ;
439476
440477 /**
@@ -450,30 +487,6 @@ export class ProtocolMonitorDataGrid extends Common.ObjectWrapper.eventMixin<Eve
450487 } , { jslogContext : 'documentation' } ) ;
451488 }
452489
453- #createCommandInput( ) : UI . Toolbar . ToolbarInput {
454- const placeholder = i18nString ( UIStrings . sendRawCDPCommand ) ;
455- const accessiblePlaceholder = placeholder ;
456- const growFactor = 1 ;
457- const shrinkFactor = 0.2 ;
458- const tooltip = i18nString ( UIStrings . sendRawCDPCommandExplanation ) ;
459- const input = new UI . Toolbar . ToolbarInput (
460- placeholder ,
461- accessiblePlaceholder ,
462- growFactor ,
463- shrinkFactor ,
464- tooltip ,
465- this . #commandAutocompleteSuggestionProvider. buildTextPromptCompletions ,
466- false ,
467- 'command-input' ,
468- ) ;
469- input . addEventListener ( UI . Toolbar . ToolbarInput . Event . ENTER_PRESSED , ( ) => {
470- this . #commandAutocompleteSuggestionProvider. addEntry ( input . value ( ) ) ;
471- const { command, parameters} = parseCommandInput ( input . value ( ) ) ;
472- this . onCommandSend ( command , parameters , this . #selectedTargetId) ;
473- } ) ;
474- return input ;
475- }
476-
477490 #createTargetSelector( ) : UI . Toolbar . ToolbarComboBox {
478491 const selector = new UI . Toolbar . ToolbarComboBox ( ( ) => {
479492 this . #selectedTargetId = selector . selectedOption ( ) ?. value ;
@@ -631,14 +644,19 @@ export class CommandAutocompleteSuggestionProvider {
631644 }
632645 }
633646
647+ allSuggestions ( ) : string [ ] {
648+ const newestToOldest = [ ...this . #commandHistory] . reverse ( ) ;
649+ newestToOldest . push ( ...metadataByCommand . keys ( ) ) ;
650+ return newestToOldest ;
651+ }
652+
634653 buildTextPromptCompletions =
635654 async ( expression : string , prefix : string , force ?: boolean ) : Promise < UI . SuggestBox . Suggestions > => {
636655 if ( ! prefix && ! force && expression ) {
637656 return [ ] ;
638657 }
639658
640- const newestToOldest = [ ...this . #commandHistory] . reverse ( ) ;
641- newestToOldest . push ( ...metadataByCommand . keys ( ) ) ;
659+ const newestToOldest = this . allSuggestions ( ) ;
642660 return newestToOldest . filter ( cmd => cmd . startsWith ( prefix ) ) . map ( text => ( {
643661 text,
644662 } ) ) ;
0 commit comments