mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 21:11:28 +07:00
[html] WEB-70082 Additional fix for XmlTagInsertHandler
(cherry picked from commit 91f1abe007d55340b1e6c233fe50b139c213d480) IJ-CR-157802 GitOrigin-RevId: 9bc901bb647318f54951cfdce7af4e807933df37
This commit is contained in:
committed by
intellij-monorepo-bot
parent
6b04c400ee
commit
dda02655d5
@@ -29,6 +29,7 @@ import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.progress.util.ProgressIndicatorUtils;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
@@ -212,14 +213,7 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
|
||||
}
|
||||
}
|
||||
|
||||
XmlAttributeDescriptor[] attributes;
|
||||
if (ApplicationManager.getApplication().isHeadlessEnvironment() || ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
attributes = descriptor.getAttributesDescriptors(tag);
|
||||
}
|
||||
else {
|
||||
// Try not to block EDT for a long time
|
||||
attributes = ProgressIndicatorUtils.withTimeout(500, () -> descriptor.getAttributesDescriptors(tag));
|
||||
}
|
||||
XmlAttributeDescriptor[] attributes = getAttributesDescriptors(descriptor, tag);
|
||||
|
||||
if (attributes == null || attributes.length == 0) {
|
||||
return null;
|
||||
@@ -289,14 +283,14 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
|
||||
}
|
||||
else if (completionChar == ' ' && template.getSegmentsCount() == 0) {
|
||||
if (WebEditorOptions.getInstance().isAutomaticallyStartAttribute() &&
|
||||
(descriptor.getAttributesDescriptors(tag).length > 0 || isTagFromHtml(tag) && !HtmlUtil.isTagWithoutAttributes(tag.getName()))) {
|
||||
(getAttributesDescriptors(descriptor, tag).length > 0 || isTagFromHtml(tag) && !HtmlUtil.isTagWithoutAttributes(tag.getName()))) {
|
||||
completeAttribute(tag.getContainingFile(), template);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (completionChar == Lookup.AUTO_INSERT_SELECT_CHAR || completionChar == Lookup.NORMAL_SELECT_CHAR || completionChar == Lookup.REPLACE_SELECT_CHAR) {
|
||||
if (WebEditorOptions.getInstance().isAutomaticallyInsertClosingTag() && isHtmlCode && HtmlUtil.isSingleHtmlTag(tag, true)) {
|
||||
if (hasOwnAttributes(descriptor, tag)) {
|
||||
if (runWithTimeoutOrNull(() -> hasOwnAttributes(descriptor, tag)) == Boolean.TRUE) {
|
||||
template.addEndVariable();
|
||||
}
|
||||
template.addTextSegment(HtmlUtil.isHtmlTag(tag) ? ">" : closeTag(tag));
|
||||
@@ -410,12 +404,12 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
|
||||
}
|
||||
|
||||
private static boolean hasOwnAttributes(XmlElementDescriptor descriptor, XmlTag tag) {
|
||||
return ContainerUtil.find(descriptor.getAttributesDescriptors(tag),
|
||||
return ContainerUtil.find(getAttributesDescriptors(descriptor, tag),
|
||||
attr -> attr instanceof HtmlAttributeDescriptorImpl && HtmlUtil.isOwnHtmlAttribute(attr)) != null;
|
||||
}
|
||||
|
||||
private static boolean canHaveAttributes(XmlElementDescriptor descriptor, XmlTag context) {
|
||||
XmlAttributeDescriptor[] attributes = descriptor.getAttributesDescriptors(context);
|
||||
XmlAttributeDescriptor[] attributes = getAttributesDescriptors(descriptor, context);
|
||||
int required = WebEditorOptions.getInstance().isAutomaticallyInsertRequiredAttributes() ?
|
||||
ArraysKt.count(attributes, (attribute) -> attribute.isRequired() && context.getAttribute(attribute.getName()) == null) :
|
||||
0;
|
||||
@@ -430,4 +424,17 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
|
||||
final String ns = tag.getNamespace();
|
||||
return XmlUtil.XHTML_URI.equals(ns) || XmlUtil.HTML_URI.equals(ns);
|
||||
}
|
||||
|
||||
private static XmlAttributeDescriptor[] getAttributesDescriptors(XmlElementDescriptor descriptor, XmlTag tag) {
|
||||
var result = runWithTimeoutOrNull(() -> descriptor.getAttributesDescriptors( tag));
|
||||
return result != null ? result : XmlAttributeDescriptor.EMPTY;
|
||||
}
|
||||
|
||||
public static <T> @Nullable T runWithTimeoutOrNull(Computable<@NotNull T> block) {
|
||||
if (ApplicationManager.getApplication().isHeadlessEnvironment() || ApplicationManager.getApplication().isUnitTestMode())
|
||||
return block.get();
|
||||
else
|
||||
return ProgressIndicatorUtils.withTimeout(250, block);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,12 +4,10 @@ package com.intellij.html.webSymbols.attributes
|
||||
import com.intellij.codeInsight.completion.CompletionParameters
|
||||
import com.intellij.codeInsight.completion.CompletionResultSet
|
||||
import com.intellij.codeInsight.completion.XmlAttributeInsertHandler
|
||||
import com.intellij.codeInsight.completion.XmlTagInsertHandler
|
||||
import com.intellij.html.webSymbols.HtmlDescriptorUtils.getStandardHtmlAttributeDescriptors
|
||||
import com.intellij.html.webSymbols.WebSymbolsFrameworkHtmlSupport
|
||||
import com.intellij.html.webSymbols.WebSymbolsHtmlQueryConfigurator
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.progress.runBlockingMaybeCancellable
|
||||
import com.intellij.openapi.progress.util.ProgressIndicatorUtils
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.psi.xml.XmlAttribute
|
||||
@@ -21,20 +19,20 @@ import com.intellij.webSymbols.completion.WebSymbolsCompletionProviderBase
|
||||
import com.intellij.webSymbols.query.WebSymbolsQueryExecutor
|
||||
import com.intellij.webSymbols.query.WebSymbolsQueryExecutorFactory
|
||||
import com.intellij.webSymbols.utils.asSingleSymbol
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
|
||||
class WebSymbolAttributeNameCompletionProvider : WebSymbolsCompletionProviderBase<XmlAttribute>() {
|
||||
|
||||
override fun getContext(position: PsiElement): XmlAttribute? =
|
||||
PsiTreeUtil.getParentOfType(position, XmlAttribute::class.java)
|
||||
|
||||
override fun addCompletions(parameters: CompletionParameters,
|
||||
result: CompletionResultSet,
|
||||
position: Int,
|
||||
name: String,
|
||||
queryExecutor: WebSymbolsQueryExecutor,
|
||||
context: XmlAttribute) {
|
||||
override fun addCompletions(
|
||||
parameters: CompletionParameters,
|
||||
result: CompletionResultSet,
|
||||
position: Int,
|
||||
name: String,
|
||||
queryExecutor: WebSymbolsQueryExecutor,
|
||||
context: XmlAttribute,
|
||||
) {
|
||||
val tag = context.parent ?: return
|
||||
val patchedResultSet = result.withPrefixMatcher(
|
||||
AsteriskAwarePrefixMatcher(result.prefixMatcher.cloneWithPrefix(name)))
|
||||
@@ -78,8 +76,8 @@ class WebSymbolAttributeNameCompletionProvider : WebSymbolsCompletionProviderBas
|
||||
val fullName = name.substring(0, item.offset) + item.name
|
||||
val match = freshRegistry.runNameMatchQuery(NAMESPACE_HTML, KIND_HTML_ATTRIBUTES, fullName)
|
||||
.asSingleSymbol() ?: return@withInsertHandlerAdded
|
||||
val info = runWithTimeoutOrNull {
|
||||
WebSymbolHtmlAttributeInfo.create(fullName, freshRegistry, match, insertionContext.file)
|
||||
val info = XmlTagInsertHandler.runWithTimeoutOrNull {
|
||||
WebSymbolHtmlAttributeInfo.create(fullName, freshRegistry, match, insertionContext.file)
|
||||
}
|
||||
if (info != null && info.acceptsValue && !info.acceptsNoValue) {
|
||||
XmlAttributeInsertHandler.INSTANCE.handleInsert(insertionContext, lookupItem)
|
||||
@@ -102,12 +100,4 @@ class WebSymbolAttributeNameCompletionProvider : WebSymbolsCompletionProviderBas
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Suppress("UsagesOfObsoleteApi")
|
||||
private fun <T> runWithTimeoutOrNull(block: () -> T): T? =
|
||||
if (ApplicationManager.getApplication().isHeadlessEnvironment() || ApplicationManager.getApplication().isUnitTestMode())
|
||||
block()
|
||||
else
|
||||
ProgressIndicatorUtils.withTimeout(250, block)
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user