diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index ee00f67e75..8c4450c1bb 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -2293,12 +2293,17 @@ public class Functions { return null; } - StaplerRequest currentRequest = Stapler.getCurrentRequest(); - currentRequest.getWebApp().getDispatchValidator().allowDispatch(currentRequest, Stapler.getCurrentResponse()); Icon iconMetadata = IconSet.icons.getIconByClassSpec(iconGuess); + // `iconGuess` must be class names if it contains a whitespace. + // It may contains extra css classes unrelated to icons. + // Filter classes with `icon-` prefix. + if (iconMetadata == null && iconGuess.contains(" ")) { + iconMetadata = IconSet.icons.getIconByClassSpec(filterIconNameClasses(iconGuess)); + } + if (iconMetadata == null) { - // Icon could be provided as a simple iconFileName e.g. "settings.png" + // Icon could be provided as a simple iconFileName e.g. "help.svg" iconMetadata = IconSet.icons.getIconByClassSpec(IconSet.toNormalizedIconNameClass(iconGuess) + " icon-md"); } @@ -2310,6 +2315,12 @@ public class Functions { return iconMetadata; } + private static @NonNull String filterIconNameClasses(@NonNull String classNames) { + return Arrays.stream(StringUtils.split(classNames, ' ')) + .filter(className -> className.startsWith("icon-")) + .collect(Collectors.joining(" ")); + } + @Restricted(NoExternalUse.class) public static String extractPluginNameFromIconSrc(String iconSrc) { if (iconSrc == null) { diff --git a/core/src/main/java/org/jenkins/ui/icon/Icon.java b/core/src/main/java/org/jenkins/ui/icon/Icon.java index d4a5e9910c..c639c5cbb7 100644 --- a/core/src/main/java/org/jenkins/ui/icon/Icon.java +++ b/core/src/main/java/org/jenkins/ui/icon/Icon.java @@ -68,7 +68,7 @@ public class Icon { /** * Creates a {@link IconType#CORE core} icon. * - * @param classSpec The icon class names. + * @param classSpec The icon class names. Expected to start with `icon-`. * @param style The icon style. */ public Icon(String classSpec, String style) { @@ -78,7 +78,7 @@ public class Icon { /** * Creates a {@link IconType#CORE core} icon. * - * @param classSpec The icon class names. + * @param classSpec The icon class names. Expected to start with `icon-`. * @param url The icon image url. * @param style The icon style. */ @@ -96,7 +96,7 @@ public class Icon { /** * Icon instance. * - * @param classSpec The icon class specification. + * @param classSpec The icon class specification. Expected to start with `icon-`. * @param url The icon image url. * @param style The icon style. * @param iconType The icon type. @@ -108,7 +108,7 @@ public class Icon { /** * Creates an icon. * - * @param classSpec The icon class names. + * @param classSpec The icon class names. Expected to start with `icon-`. * @param url The icon image url. * @param style The icon style. * @param iconFormat the {@link IconFormat}. diff --git a/core/src/test/java/hudson/FunctionsTest.java b/core/src/test/java/hudson/FunctionsTest.java index 85ae2ca704..fff8391321 100644 --- a/core/src/test/java/hudson/FunctionsTest.java +++ b/core/src/test/java/hudson/FunctionsTest.java @@ -28,6 +28,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.emptyString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -639,4 +641,39 @@ public class FunctionsTest { return this; } } + + @Test + public void tryGetIcon_shouldReturnNullForNull() throws Exception { + assertThat(Functions.tryGetIcon(null), is(nullValue())); + } + + @Test + public void tryGetIcon_shouldReturnNullForSymbol() throws Exception { + assertThat(Functions.tryGetIcon("symbol-search"), is(nullValue())); + } + + @Test + public void tryGetIcon_shouldReturnMetadataForExactSpec() throws Exception { + assertThat(Functions.tryGetIcon("icon-help icon-sm"), is(not(nullValue()))); + } + + @Test + public void tryGetIcon_shouldReturnMetadataForExtraSpec() throws Exception { + assertThat(Functions.tryGetIcon("icon-help icon-sm extra-class"), is(not(nullValue()))); + } + + @Test + public void tryGetIcon_shouldReturnMetadataForFilename() throws Exception { + assertThat(Functions.tryGetIcon("help.svg"), is(not(nullValue()))); + } + + @Test + public void tryGetIcon_shouldReturnMetadataForUrl() throws Exception { + assertThat(Functions.tryGetIcon("48x48/green.gif"), is(not(nullValue()))); + } + + @Test + public void tryGetIcon_shouldReturnNullForUnknown() throws Exception { + assertThat(Functions.tryGetIcon("icon-nosuchicon"), is(nullValue())); + } }