Automatically generate context string for restricted keydown tracking. Bug: chromium:1467464 Change-Id: Iffccf013520e434360f2776071eb9eae09b15d7f Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/5352348 Reviewed-by: Ergün Erdoğmuş <ergunsh@chromium.org> Commit-Queue: Ergün Erdoğmuş <ergunsh@chromium.org> Auto-Submit: Danil Somsikov <dsv@chromium.org>
diff --git a/front_end/ui/legacy/Dialog.ts b/front_end/ui/legacy/Dialog.ts index 4bd1326..7a806bc 100644 --- a/front_end/ui/legacy/Dialog.ts +++ b/front_end/ui/legacy/Dialog.ts
@@ -55,7 +55,8 @@ this.contentElement.tabIndex = 0; this.contentElement.addEventListener('focus', () => this.widget().focus(), false); if (jslogContext) { - this.contentElement.setAttribute('jslog', `${VisualLogging.dialog(jslogContext).track({resize: true})}`); + this.contentElement.setAttribute( + 'jslog', `${VisualLogging.dialog(jslogContext).track({resize: true, keydown: 'Escape'})}`); } this.widget().setDefaultFocusedElement(this.contentElement); this.setPointerEventsBehavior(PointerEventsBehavior.BlockedByGlassPane);
diff --git a/front_end/ui/legacy/Infobar.ts b/front_end/ui/legacy/Infobar.ts index 64c611b..981a7d8 100644 --- a/front_end/ui/legacy/Infobar.ts +++ b/front_end/ui/legacy/Infobar.ts
@@ -60,7 +60,8 @@ jslogContext?: string) { this.element = document.createElement('div'); if (jslogContext) { - this.element.setAttribute('jslog', `${VisualLogging.dialog(jslogContext).track({resize: true})}`); + this.element.setAttribute( + 'jslog', `${VisualLogging.dialog(jslogContext).track({resize: true, keydown: 'Enter|Escape'})}`); } this.element.classList.add('flex-none'); this.shadowRoot =
diff --git a/front_end/ui/legacy/ListControl.ts b/front_end/ui/legacy/ListControl.ts index 5c3b9c0..f9b0d2c 100644 --- a/front_end/ui/legacy/ListControl.ts +++ b/front_end/ui/legacy/ListControl.ts
@@ -361,7 +361,8 @@ if (!element) { element = this.delegate.createElementForItem(item); if (!element.hasAttribute('jslog')) { - element.setAttribute('jslog', `${VisualLogging.item().track({click: true})}`); + element.setAttribute( + 'jslog', `${VisualLogging.item().track({click: true, keydown: 'ArrowUp|ArrowDown|PageUp|PageDown'})}`); } this.itemToElement.set(item, element); this.updateElementARIA(element, index);
diff --git a/front_end/ui/legacy/ListWidget.ts b/front_end/ui/legacy/ListWidget.ts index 8d9de8b..b6eae63 100644 --- a/front_end/ui/legacy/ListWidget.ts +++ b/front_end/ui/legacy/ListWidget.ts
@@ -370,7 +370,7 @@ const input = (createInput('', type) as HTMLInputElement); input.placeholder = title; input.addEventListener('input', this.validateControls.bind(this, false), false); - input.setAttribute('jslog', `${VisualLogging.textField().track({keydown: true}).context(name)}`); + input.setAttribute('jslog', `${VisualLogging.textField().track({change: true, keydown: 'Enter'}).context(name)}`); ARIAUtils.setLabel(input, title); this.controlByName.set(name, input); this.controls.push(input);
diff --git a/front_end/ui/legacy/SearchableView.ts b/front_end/ui/legacy/SearchableView.ts index d8b51e8..d1cdaa4 100644 --- a/front_end/ui/legacy/SearchableView.ts +++ b/front_end/ui/legacy/SearchableView.ts
@@ -153,7 +153,9 @@ this.searchInputElement.classList.add('search-replace', 'custom-search-input'); this.searchInputElement.id = 'search-input-field'; this.searchInputElement.placeholder = i18nString(UIStrings.findString); - this.searchInputElement.setAttribute('jslog', `${VisualLogging.textField('search').track({change: true})}`); + this.searchInputElement.setAttribute( + 'jslog', + `${VisualLogging.textField('search').track({change: true, keydown: 'ArrowUp|ArrowDown|Enter|Escape'})}`); searchControlElement.appendChild(this.searchInputElement); this.matchesElement = searchControlElement.createChild('label', 'search-results-matches'); @@ -183,7 +185,8 @@ (searchInputElements.createChild('input', 'search-replace toolbar-replace-control hidden') as HTMLInputElement); this.replaceInputElement.addEventListener('keydown', this.onReplaceKeyDown.bind(this), true); this.replaceInputElement.placeholder = i18nString(UIStrings.replace); - this.replaceInputElement.setAttribute('jslog', `${VisualLogging.textField('replace').track({change: true})}`); + this.replaceInputElement.setAttribute( + 'jslog', `${VisualLogging.textField('replace').track({change: true, keydown: 'Enter'})}`); this.buttonsContainer = this.footerElement.createChild('div', 'toolbar-search-buttons'); const firstRowButtons = this.buttonsContainer.createChild('div', 'first-row-buttons');
diff --git a/front_end/ui/legacy/SoftContextMenu.ts b/front_end/ui/legacy/SoftContextMenu.ts index 326bbc0..77c39d5 100644 --- a/front_end/ui/legacy/SoftContextMenu.ts +++ b/front_end/ui/legacy/SoftContextMenu.ts
@@ -121,7 +121,9 @@ this.glassPane.setAnchorBehavior(this.parentMenu ? AnchorBehavior.PreferRight : AnchorBehavior.PreferBottom); this.contextMenuElement = this.glassPane.contentElement.createChild('div', 'soft-context-menu'); - this.contextMenuElement.setAttribute('jslog', `${VisualLogging.menu().track({resize: true}).parent('mapped')}`); + this.contextMenuElement.setAttribute('jslog', `${VisualLogging.menu().track({resize: true}).parent('mapped').track({ + keydown: 'ArrowUp|ArrowDown|ArrowLeft|ArrowRight|Enter|Space|Escape', + })}`); if (this.loggableParent) { VisualLogging.setMappedParent(this.contextMenuElement, this.loggableParent); }
diff --git a/front_end/ui/legacy/SoftDropDown.ts b/front_end/ui/legacy/SoftDropDown.ts index 6e75a58..762a193 100644 --- a/front_end/ui/legacy/SoftDropDown.ts +++ b/front_end/ui/legacy/SoftDropDown.ts
@@ -77,7 +77,9 @@ .appendChild(this.list.element); ARIAUtils.markAsMenu(this.list.element); VisualLogging.setMappedParent(this.list.element, this.element); - this.list.element.setAttribute('jslog', `${VisualLogging.menu().parent('mapped').track({resize: true})}`); + this.list.element.setAttribute( + 'jslog', + `${VisualLogging.menu().parent('mapped').track({resize: true, keydown: 'ArrowUp|ArrowDown|PageUp|PageDown'})}`); this.listWasShowing200msAgo = false; this.element.addEventListener('mousedown', event => {
diff --git a/front_end/ui/legacy/Treeoutline.ts b/front_end/ui/legacy/Treeoutline.ts index f78cbf4..25d7a4c 100644 --- a/front_end/ui/legacy/Treeoutline.ts +++ b/front_end/ui/legacy/Treeoutline.ts
@@ -470,7 +470,9 @@ this.listItemNode.addEventListener('click', (this.treeElementToggled.bind(this) as EventListener), false); this.listItemNode.addEventListener('dblclick', this.handleDoubleClick.bind(this), false); this.listItemNode.setAttribute( - 'jslog', `${VisualLogging.treeItem().parent('parentTreeItem').context(jslogContext)}`); + 'jslog', `${VisualLogging.treeItem().parent('parentTreeItem').context(jslogContext).track({ + keydown: 'ArrowUp|ArrowDown|ArrowLeft|ArrowRight|Backspace|Delete|Enter|Space|Home|End', + })}`); ARIAUtils.markAsTreeitem(this.listItemNode); this.childrenInternal = null;
diff --git a/front_end/ui/legacy/UIUtils.ts b/front_end/ui/legacy/UIUtils.ts index 65240d6..b87a89a 100644 --- a/front_end/ui/legacy/UIUtils.ts +++ b/front_end/ui/legacy/UIUtils.ts
@@ -1108,7 +1108,8 @@ element.type = type; } if (jslogContext) { - element.setAttribute('jslog', `${VisualLogging.textField().track({keydown: true}).context(jslogContext)}`); + element.setAttribute( + 'jslog', `${VisualLogging.textField().track({keydown: 'Enter', change: true}).context(jslogContext)}`); } return element; }
diff --git a/front_end/ui/legacy/ViewManager.ts b/front_end/ui/legacy/ViewManager.ts index 14debbc..98e94f8 100644 --- a/front_end/ui/legacy/ViewManager.ts +++ b/front_end/ui/legacy/ViewManager.ts
@@ -424,8 +424,10 @@ this.titleElement = document.createElement('div'); this.titleElement.classList.add('expandable-view-title'); - this.titleElement.setAttribute( - 'jslog', `${VisualLogging.sectionHeader().context(view.viewId()).track({click: true})}`); + this.titleElement.setAttribute('jslog', `${VisualLogging.sectionHeader().context(view.viewId()).track({ + click: true, + keydown: 'Enter|Space|ArrowLeft|ArrowRight', + })}`); ARIAUtils.markAsTreeitem(this.titleElement); this.titleExpandIcon = IconButton.Icon.create('triangle-right', 'title-expand-icon'); this.titleElement.appendChild(this.titleExpandIcon);
diff --git a/front_end/ui/legacy/XLink.ts b/front_end/ui/legacy/XLink.ts index 17eb35b..d60fb0e 100644 --- a/front_end/ui/legacy/XLink.ts +++ b/front_end/ui/legacy/XLink.ts
@@ -34,7 +34,7 @@ // TODO(dgozman): migrate css from 'devtools-link' to 'x-link'. const element = html ` <x-link href='${url}' tabindex="0" class='${className} devtools-link' ${preventClick ? 'no-click' : ''} - jslog=${VisualLogging.link().track({click: true}).context(jsLogContext)}>${Platform.StringUtilities.trimMiddle(linkText, MaxLengthForDisplayedURLs)}</x-link>`; + jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context(jsLogContext)}>${Platform.StringUtilities.trimMiddle(linkText, MaxLengthForDisplayedURLs)}</x-link>`; // clang-format on return element as HTMLElement; }
diff --git a/front_end/ui/visual_logging/LoggingEvents.test.ts b/front_end/ui/visual_logging/LoggingEvents.test.ts index 6656d6f..645e56a 100644 --- a/front_end/ui/visual_logging/LoggingEvents.test.ts +++ b/front_end/ui/visual_logging/LoggingEvents.test.ts
@@ -95,11 +95,11 @@ Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'recordKeyDown', ); - const event = new KeyboardEvent('keydown', {code: 'Enter'}); + const event = new KeyboardEvent('keydown', {code: 'Enter', key: 'Enter'}); sinon.stub(event, 'currentTarget').value(element); void VisualLogging.LoggingEvents.logKeyDown(throttler, ['Enter', 'Escape'])(event); await assertThrottled(recordKeyDown); - assert.deepStrictEqual(stabilizeEvent(recordKeyDown.firstCall.firstArg), {veid: 0}); + assert.deepStrictEqual(stabilizeEvent(recordKeyDown.firstCall.firstArg), {veid: 0, context: 513111094}); }); it('calls UI binding to log a keydown with an provided context', async () => {
diff --git a/front_end/ui/visual_logging/LoggingEvents.ts b/front_end/ui/visual_logging/LoggingEvents.ts index e9b964d..a232246 100644 --- a/front_end/ui/visual_logging/LoggingEvents.ts +++ b/front_end/ui/visual_logging/LoggingEvents.ts
@@ -100,6 +100,9 @@ } const loggingState = event?.currentTarget ? getLoggingState(event.currentTarget) : null; const keyDownEvent: Host.InspectorFrontendHostAPI.KeyDownEvent = {veid: loggingState?.veid}; + if (!context && codes?.length) { + context = contextFromKeyCodes(event); + } if (context) { keyDownEvent.context = await contextAsNumber(context); } @@ -109,6 +112,27 @@ }); }; +function contextFromKeyCodes(event: Event): string|undefined { + if (!(event instanceof KeyboardEvent)) { + return undefined; + } + const components = []; + if (event.shiftKey) { + components.push('shift'); + } + if (event.ctrlKey) { + components.push('ctrl'); + } + if (event.altKey) { + components.push('alt'); + } + if (event.metaKey) { + components.push('meta'); + } + components.push(event.key.toLowerCase()); + return components.join('-'); +} + async function contextAsNumber(context: string|undefined): Promise<number|undefined> { if (typeof context === 'undefined') { return undefined;