[json] IDEA-293580 Make plain text URLs as clickable in JSON string value

GitOrigin-RevId: 27b6b76e694b943cc62db417cf8a390c71c132f1
This commit is contained in:
Yuriy Artamonov
2022-05-05 17:58:09 +02:00
committed by intellij-monorepo-bot
parent ab3f21997a
commit 8119f88ac4
4 changed files with 68 additions and 0 deletions

View File

@@ -137,6 +137,8 @@
</intentionAction>
<notificationGroup id="JSON Schema" displayType="NONE"/>
<psi.referenceContributor language="JSON" implementation="com.intellij.json.JsonWebReferenceContributor"/>
<lang.parserDefinition language="JSONPath" implementationClass="com.intellij.jsonpath.psi.JsonPathParserDefinition"/>
<lang.braceMatcher language="JSONPath" implementationClass="com.intellij.jsonpath.JsonPathPairedBraceMatcher"/>
<lang.quoteHandler language="JSONPath" implementationClass="com.intellij.jsonpath.JsonPathQuoteHandler"/>

View File

@@ -0,0 +1,56 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.json;
import com.intellij.json.psi.JsonProperty;
import com.intellij.json.psi.JsonStringLiteral;
import com.intellij.json.psi.JsonValue;
import com.intellij.openapi.paths.GlobalPathReferenceProvider;
import com.intellij.openapi.paths.WebReference;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
import static com.intellij.patterns.PlatformPatterns.psiElement;
final class JsonWebReferenceContributor extends PsiReferenceContributor {
@Override
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(
psiElement(JsonStringLiteral.class),
new PsiReferenceProvider() {
@Override
public boolean acceptsTarget(@NotNull PsiElement target) {
return false; // web references do not point to any real PsiElement
}
@Override
public PsiReference @NotNull [] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
if (!(element instanceof JsonStringLiteral)) return PsiReference.EMPTY_ARRAY;
JsonStringLiteral stringLiteral = (JsonStringLiteral)element;
PsiElement parent = stringLiteral.getParent();
if (!(parent instanceof JsonProperty)) return PsiReference.EMPTY_ARRAY;
JsonValue jsonValueElement = ((JsonProperty)parent).getValue();
if (element != jsonValueElement) return PsiReference.EMPTY_ARRAY;
if (element.getTextLength() > 1000) return PsiReference.EMPTY_ARRAY; // JSON may be used as data format for huge strings
if (!element.textContains(':')) return PsiReference.EMPTY_ARRAY;
String textValue = stringLiteral.getValue();
if (GlobalPathReferenceProvider.isWebReferenceUrl(textValue)) {
TextRange valueTextRange = ElementManipulators.getValueTextRange(stringLiteral);
if (valueTextRange.isEmpty()) return PsiReference.EMPTY_ARRAY;
return new PsiReference[]{new WebReference(element, valueTextRange, textValue)};
}
return PsiReference.EMPTY_ARRAY;
}
},
PsiReferenceRegistrar.LOWER_PRIORITY
);
}
}

View File

@@ -87,6 +87,10 @@ public class JsonHighlightingTest extends JsonHighlightingTestBase {
doTest();
}
public void testWebUrls() {
doTest();
}
public void testRainbow() {
myFixture.testRainbow("test.json",
"{\n" +

View File

@@ -0,0 +1,6 @@
{
<info descr="Property key">"some"</info>: "<info>http://localhost</info>",
<info descr="Property key">"secure"</info>: "<info>https://localhost</info>",
<info descr="Property key">"not-url"</info>: "https :// localhost",
<info descr="Property key">"https://key-not-checked"</info>: "value"
}