From c4dd21946bffb5deb011a16168cdae224c8dd7ab Mon Sep 17 00:00:00 2001 From: emmebi Date: Sat, 18 Mar 2023 11:46:20 +0000 Subject: [PATCH 1/2] Strips HTML tags from code completion list Fixes #391 --- .../client/ui/syntax/HTMLTagRemover.java | 30 ++++++++++ .../ui/syntax/MapToolScriptAutoComplete.java | 36 +++++++----- .../client/ui/syntax/HTMLTagRemoverTest.java | 56 +++++++++++++++++++ .../syntax/MapToolScriptAutoCompleteTest.java | 41 ++++++++++++++ 4 files changed, 150 insertions(+), 13 deletions(-) create mode 100644 src/main/java/net/rptools/maptool/client/ui/syntax/HTMLTagRemover.java create mode 100644 src/test/java/net/rptools/maptool/client/ui/syntax/HTMLTagRemoverTest.java create mode 100644 src/test/java/net/rptools/maptool/client/ui/syntax/MapToolScriptAutoCompleteTest.java diff --git a/src/main/java/net/rptools/maptool/client/ui/syntax/HTMLTagRemover.java b/src/main/java/net/rptools/maptool/client/ui/syntax/HTMLTagRemover.java new file mode 100644 index 0000000000..fe691f902d --- /dev/null +++ b/src/main/java/net/rptools/maptool/client/ui/syntax/HTMLTagRemover.java @@ -0,0 +1,30 @@ +/* + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. + * + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . + */ +package net.rptools.maptool.client.ui.syntax; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +public class HTMLTagRemover { + /* The following expression relies on the non-greediness of the replaceAll function */ + private static final String HTML_TAG_REGEX = "<[^>]*>"; + + private static final ConcurrentMap htmlCache = new ConcurrentHashMap<>(); + + String remove(String htmlString) { + if (htmlString == null) return null; + return htmlCache.computeIfAbsent(htmlString, s -> s.replaceAll(HTML_TAG_REGEX, "")); + } +} diff --git a/src/main/java/net/rptools/maptool/client/ui/syntax/MapToolScriptAutoComplete.java b/src/main/java/net/rptools/maptool/client/ui/syntax/MapToolScriptAutoComplete.java index 40a6309504..9da5346dfc 100644 --- a/src/main/java/net/rptools/maptool/client/ui/syntax/MapToolScriptAutoComplete.java +++ b/src/main/java/net/rptools/maptool/client/ui/syntax/MapToolScriptAutoComplete.java @@ -38,6 +38,7 @@ public class MapToolScriptAutoComplete { private static final String I18N_SHORT_DESCRIPTION = ".description"; private static final String I18N_SUMMARY = ".summary"; private static final String I18N_PLACEHOLDER_TEXT = "TBD"; + private static final HTMLTagRemover htmlTagRemover = new HTMLTagRemover(); DefaultCompletionProvider provider = new DefaultCompletionProvider() { @@ -50,7 +51,11 @@ protected boolean isValidChar(char ch) { public MapToolScriptAutoComplete() { for (String macro : MapTool.getParser().listAllMacroFunctions().keySet()) provider.addCompletion( - new BasicCompletion(provider, macro, getShortDescription(macro), getSummary(macro))); + new BasicCompletion( + provider, + macro, + htmlTagRemover.remove(getShortDescription(macro)), + getSummary(macro))); // Add UDFs UserDefinedMacroFunctions udfManager = UserDefinedMacroFunctions.getInstance(); @@ -62,7 +67,7 @@ public MapToolScriptAutoComplete() { new BasicCompletion( provider, udf, - udfManager.getFunctionDescription(udf), + htmlTagRemover.remove(udfManager.getFunctionDescription(udf)), (StringUtils.isBlank(udfSummary)) ? null : udfSummary)); } @@ -70,19 +75,28 @@ public MapToolScriptAutoComplete() { for (String dataType : MapToolScriptSyntax.DATA_TYPES) provider.addCompletion( new BasicCompletion( - provider, dataType, getShortDescription(dataType), getSummary(dataType))); + provider, + dataType, + htmlTagRemover.remove(getShortDescription(dataType)), + getSummary(dataType))); // Add "Roll Options" as Reserved word for (String reservedWord : MapToolScriptSyntax.RESERVED_WORDS) provider.addCompletion( new BasicCompletion( - provider, reservedWord, getShortDescription(reservedWord), getSummary(reservedWord))); + provider, + reservedWord, + htmlTagRemover.remove(getShortDescription(reservedWord)), + getSummary(reservedWord))); // Add "Events" as Reserved Word 2 for (String reservedWord : MapToolScriptSyntax.RESERVED_WORDS_2) provider.addCompletion( new BasicCompletion( - provider, reservedWord, getShortDescription(reservedWord), getSummary(reservedWord))); + provider, + reservedWord, + htmlTagRemover.remove(getShortDescription(reservedWord)), + getSummary(reservedWord))); for (Function function : MapToolExpressionParser.getMacroFunctions()) { if (function instanceof DefinesSpecialVariables) { @@ -91,7 +105,7 @@ public MapToolScriptAutoComplete() { new BasicCompletion( provider, specialVariable, - getShortDescription(specialVariable), + htmlTagRemover.remove(getShortDescription(specialVariable)), getSummary(specialVariable))); } } @@ -162,10 +176,8 @@ private String getShortDescription(String macro) { // if there is no shortDesc try if one of the functions has one if (shortDesc == null) { for (Function function : MapToolExpressionParser.getMacroFunctions()) { - if (function instanceof AdditionalFunctionDescription) { - final AdditionalFunctionDescription functionExtended = - (AdditionalFunctionDescription) function; - // try if the function has a summary for this macro + if (function instanceof AdditionalFunctionDescription functionExtended) { + // try if the function has a shortDesc for this macro final String shortDescExtended = functionExtended.getFunctionDescription(macro); if (shortDescExtended != null) { return shortDescExtended; @@ -185,9 +197,7 @@ private String getSummary(String macro) { // if there is no summary try if one of the functions has one if (summary == null) { for (final Function function : MapToolExpressionParser.getMacroFunctions()) { - if (function instanceof AdditionalFunctionDescription) { - final AdditionalFunctionDescription functionExtended = - (AdditionalFunctionDescription) function; + if (function instanceof AdditionalFunctionDescription functionExtended) { // try if the function has a summary for this macro final String summaryExtended = functionExtended.getFunctionSummary(macro); if (summaryExtended != null) { diff --git a/src/test/java/net/rptools/maptool/client/ui/syntax/HTMLTagRemoverTest.java b/src/test/java/net/rptools/maptool/client/ui/syntax/HTMLTagRemoverTest.java new file mode 100644 index 0000000000..a2212f2b39 --- /dev/null +++ b/src/test/java/net/rptools/maptool/client/ui/syntax/HTMLTagRemoverTest.java @@ -0,0 +1,56 @@ +/* + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. + * + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . + */ +package net.rptools.maptool.client.ui.syntax; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class HTMLTagRemoverTest { + + private final HTMLTagRemover remover = new HTMLTagRemover(); + + @Test + void nullRemainsNull() { + assertEquals(null, remover.remove(null)); + } + + @Test + void emptyStringRemainsEmpty() { + assertEquals("", remover.remove("")); + } + + @Test + void openTagsAreRemoved() { + assertEquals("text some text", remover.remove("text some text")); + } + + @Test + void closeTagsAreRemoved() { + assertEquals("text some text", remover.remove("text some text")); + } + + @Test + void unfinishedTagsAreNotRemoved() { + assertEquals("text more text even more text")); + } +} diff --git a/src/test/java/net/rptools/maptool/client/ui/syntax/MapToolScriptAutoCompleteTest.java b/src/test/java/net/rptools/maptool/client/ui/syntax/MapToolScriptAutoCompleteTest.java new file mode 100644 index 0000000000..3030020c39 --- /dev/null +++ b/src/test/java/net/rptools/maptool/client/ui/syntax/MapToolScriptAutoCompleteTest.java @@ -0,0 +1,41 @@ +/* + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. + * + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . + */ +package net.rptools.maptool.client.ui.syntax; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; +import org.fife.ui.autocomplete.BasicCompletion; +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.autocomplete.DefaultCompletionProvider; +import org.junit.jupiter.api.Test; + +class MapToolScriptAutoCompleteTest { + + @Test + void tagsAreStrippedFromAShortDesc() { + MapToolScriptAutoComplete mapToolScriptAutoComplete = new MapToolScriptAutoComplete(); + DefaultCompletionProvider completionProvider = + (DefaultCompletionProvider) mapToolScriptAutoComplete.get(); + + List completionList = completionProvider.getCompletionByInputText("json.length"); + + assertEquals(1, completionList.size()); + BasicCompletion completion = (BasicCompletion) completionList.get(0); + assertEquals( + "Returns the number of fields in a json object or number of elements in a json array .", + completion.getShortDescription()); + } +} From 8bcc890f13310d8a706007f72333170b7eb5489f Mon Sep 17 00:00:00 2001 From: emmebi Date: Thu, 23 Mar 2023 21:53:02 +0000 Subject: [PATCH 2/2] Coding style compliance Refers #391 --- .../net/rptools/maptool/client/ui/syntax/HTMLTagRemover.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/rptools/maptool/client/ui/syntax/HTMLTagRemover.java b/src/main/java/net/rptools/maptool/client/ui/syntax/HTMLTagRemover.java index fe691f902d..93ff47f1f0 100644 --- a/src/main/java/net/rptools/maptool/client/ui/syntax/HTMLTagRemover.java +++ b/src/main/java/net/rptools/maptool/client/ui/syntax/HTMLTagRemover.java @@ -24,7 +24,9 @@ public class HTMLTagRemover { private static final ConcurrentMap htmlCache = new ConcurrentHashMap<>(); String remove(String htmlString) { - if (htmlString == null) return null; + if (htmlString == null) { + return null; + } return htmlCache.computeIfAbsent(htmlString, s -> s.replaceAll(HTML_TAG_REGEX, "")); } }