From 1c5793e697d124cefea5866bbea85d5ab519834a Mon Sep 17 00:00:00 2001 From: Ishan Taldekar Date: Tue, 18 Feb 2025 12:49:47 -0500 Subject: [PATCH] Fix Mynah UI checkstyle issues (#369) --- .../amazonq/views/AmazonQChatWebview.java | 187 ++++++++++-------- 1 file changed, 102 insertions(+), 85 deletions(-) diff --git a/plugin/src/software/aws/toolkits/eclipse/amazonq/views/AmazonQChatWebview.java b/plugin/src/software/aws/toolkits/eclipse/amazonq/views/AmazonQChatWebview.java index 37d69326..36e79a0c 100644 --- a/plugin/src/software/aws/toolkits/eclipse/amazonq/views/AmazonQChatWebview.java +++ b/plugin/src/software/aws/toolkits/eclipse/amazonq/views/AmazonQChatWebview.java @@ -280,77 +280,120 @@ private String generateJS(final String jsEntrypoint) { window.addEventListener('load', init); - window.addEventListener('load', () => { - const textarea = document.querySelector('textarea.mynah-chat-prompt-input'); - if (textarea) { - textarea.addEventListener('keydown', (event) => { - const cursorPosition = textarea.selectionStart; - const hasText = textarea.value.length > 0; - - // block arrow keys on empty text area - switch (event.key) { - case 'ArrowLeft': - if (!hasText || cursorPosition === 0) { - event.preventDefault(); - event.stopPropagation(); - } - break; - - case 'ArrowRight': - if (!hasText || cursorPosition === textarea.value.length) { - event.preventDefault(); - event.stopPropagation(); - } - break; - } - }); - } - }); + %s - window.addEventListener('load', () => { - const textarea = document.querySelector('textarea.mynah-chat-prompt-input'); - if (textarea) { - textarea.addEventListener("keydown", (event) => { - if (((isMacOs() && event.metaKey) || (!isMacOs() && event.ctrlKey)) - && event.key === 'a') { - textarea.select(); - event.preventDefault(); - event.stopPropagation(); - } - }); - } - }); + %s - window.addEventListener('load', () => { - const textarea = document.querySelector('textarea.mynah-chat-prompt-input'); - if (textarea) { - textarea.addEventListener("keydown", (event) => { - if (((isMacOs() && event.metaKey) || (!isMacOs() && event.ctrlKey)) && event.key === 'c') { - copyToClipboard(textarea.value); - event.preventDefault(); - event.stopPropagation(); - } - }); - } - }); + %s + + + """, jsEntrypoint, getWaitFunction(), chatQuickActionConfig, + "true".equals(disclaimerAcknowledged), getArrowKeyBlockingFunction(), + getSelectAllAndCopySupportFunctions(), getPreventEmptyPopupFunction()); + } + + /* + * Generates javascript for chat options to be supplied to Chat UI defined here + * https://github.com/aws/language-servers/blob/ + * 785f8dee86e9f716fcfa29b2e27eb07a02387557/chat-client/src/client/chat.ts#L87 + */ + private String generateQuickActionConfig() { + return Optional.ofNullable(AwsServerCapabiltiesProvider.getInstance().getChatOptions()) + .map(ChatOptions::quickActions).map(QuickActions::quickActionsCommandGroups) + .map(this::serializeQuickActionCommands).orElse("[]"); + } + + private String serializeQuickActionCommands(final List quickActionCommands) { + try { + ObjectMapper mapper = ObjectMapperFactory.getInstance(); + return mapper.writeValueAsString(quickActionCommands); + } catch (Exception e) { + Activator.getLogger().warn("Error occurred when json serializing quick action commands", e); + return ""; + } + } + + private String getArrowKeyBlockingFunction() { + return """ + window.addEventListener('load', () => { + const textarea = document.querySelector('textarea.mynah-chat-prompt-input'); + if (textarea) { + textarea.addEventListener('keydown', (event) => { + const cursorPosition = textarea.selectionStart; + const hasText = textarea.value.length > 0; + + // block arrow keys on empty text area + switch (event.key) { + case 'ArrowLeft': + if (!hasText || cursorPosition === 0) { + event.preventDefault(); + event.stopPropagation(); + } + break; + + case 'ArrowRight': + if (!hasText || cursorPosition === textarea.value.length) { + event.preventDefault(); + event.stopPropagation(); + } + break; + } + }); + } + }); + """; + } + + private String getSelectAllAndCopySupportFunctions() { + return """ + window.addEventListener('load', () => { + const textarea = document.querySelector('textarea.mynah-chat-prompt-input'); + if (textarea) { + textarea.addEventListener("keydown", (event) => { + if (((isMacOs() && event.metaKey) || (!isMacOs() && event.ctrlKey)) + && event.key === 'a') { + textarea.select(); + event.preventDefault(); + event.stopPropagation(); + } + }); + } + }); + + window.addEventListener('load', () => { + const textarea = document.querySelector('textarea.mynah-chat-prompt-input'); + if (textarea) { + textarea.addEventListener("keydown", (event) => { + if (((isMacOs() && event.metaKey) || (!isMacOs() && event.ctrlKey)) + && event.key === 'c') { + copyToClipboard(textarea.value); + event.preventDefault(); + event.stopPropagation(); + } + }); + } + }); + """; + } + private String getPreventEmptyPopupFunction() { + String selector = ".mynah-button" + ".mynah-button-secondary.mynah-button-border" + ".fill-state-always" + + ".mynah-chat-item-followup-question-option" + ".mynah-ui-clickable-item"; + return """ const observer = new MutationObserver((mutations) => { try { + const selector = '%s'; + mutations.forEach((mutation) => { mutation.addedNodes.forEach((node) => { if (node.nodeType === 1) { // Check if it's an element node // Check for direct match - if (node.matches('.mynah-button.mynah-button-secondary - .mynah-button-border.fill-state-always.mynah-chat-item-followup-question-option - .mynah-ui-clickable-item')) { + if (node.matches(selector)) { attachEventListeners(node); } - // Check for nested matches - const buttons = node.querySelectorAll('.mynah-button.mynah-button-secondary - .mynah-button-border.fill-state-always.mynah-chat-item-followup-question-option - .mynah-ui-clickable-item'); + const buttons = node.querySelectorAll(); buttons.forEach(attachEventListeners); } }); @@ -359,10 +402,8 @@ private String generateJS(final String jsEntrypoint) { console.error('Error in mutation observer:', error); } }); - function attachEventListeners(element) { if (!element || element.dataset.hasListener) return; // Prevent duplicate listeners - element.addEventListener('mouseover', function(event) { const textSpan = this.querySelector('span.mynah-button-label'); if (textSpan && textSpan.scrollWidth <= textSpan.offsetWidth) { @@ -373,7 +414,6 @@ function attachEventListeners(element) { }, true); element.dataset.hasListener = 'true'; } - try { observer.observe(document.body, { childList: true, @@ -382,30 +422,7 @@ function attachEventListeners(element) { } catch (error) { console.error('Error starting observer:', error); } - - """, jsEntrypoint, getWaitFunction(), chatQuickActionConfig, - "true".equals(disclaimerAcknowledged)); - } - - /* - * Generates javascript for chat options to be supplied to Chat UI defined here - * https://github.com/aws/language-servers/blob/ - * 785f8dee86e9f716fcfa29b2e27eb07a02387557/chat-client/src/client/chat.ts#L87 - */ - private String generateQuickActionConfig() { - return Optional.ofNullable(AwsServerCapabiltiesProvider.getInstance().getChatOptions()) - .map(ChatOptions::quickActions).map(QuickActions::quickActionsCommandGroups) - .map(this::serializeQuickActionCommands).orElse("[]"); - } - - private String serializeQuickActionCommands(final List quickActionCommands) { - try { - ObjectMapper mapper = ObjectMapperFactory.getInstance(); - return mapper.writeValueAsString(quickActionCommands); - } catch (Exception e) { - Activator.getLogger().warn("Error occurred when json serializing quick action commands", e); - return ""; - } + """.formatted(selector); } @Override