mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
WEB-44210 Update behavior of tag completion in HTML, JSX, and XML
GitOrigin-RevId: 721caf7344143b6a6254fb0b87d3a7e98d7ab939
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f652c91582
commit
ac163e1235
@@ -36,12 +36,17 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.formatter.xml.HtmlCodeStyleSettings;
|
||||
import com.intellij.psi.formatter.xml.XmlCodeStyleSettings;
|
||||
import com.intellij.psi.html.HtmlTag;
|
||||
import com.intellij.psi.impl.source.html.dtd.HtmlAttributeDescriptorImpl;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.psi.xml.XmlTokenType;
|
||||
import com.intellij.xml.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.xml.XmlAttributeDescriptor;
|
||||
import com.intellij.xml.XmlElementDescriptor;
|
||||
import com.intellij.xml.XmlExtension;
|
||||
import com.intellij.xml.XmlExtension.AttributeValuePresentation;
|
||||
import com.intellij.xml.XmlTagRuleProvider;
|
||||
import com.intellij.xml.actions.GenerateXmlTagAction;
|
||||
import com.intellij.xml.impl.schema.XmlElementDescriptorImpl;
|
||||
import com.intellij.xml.util.HtmlUtil;
|
||||
@@ -274,10 +279,13 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
|
||||
}
|
||||
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)) {
|
||||
template.addEndVariable();
|
||||
}
|
||||
template.addTextSegment(HtmlUtil.isHtmlTag(tag) ? ">" : closeTag(tag));
|
||||
}
|
||||
else {
|
||||
if (needAlLeastOneAttribute(tag) && WebEditorOptions.getInstance().isAutomaticallyStartAttribute() && tag.getAttributes().length == 0
|
||||
if (needAtLeastOneAttribute(tag) && WebEditorOptions.getInstance().isAutomaticallyStartAttribute() && tag.getAttributes().length == 0
|
||||
&& template.getSegmentsCount() == 0) {
|
||||
completeAttribute(tag.getContainingFile(), template);
|
||||
return true;
|
||||
@@ -308,7 +316,7 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
|
||||
template.addTextSegment(XmlEditUtil.getAttributeQuote(file));
|
||||
}
|
||||
|
||||
private static boolean needAlLeastOneAttribute(XmlTag tag) {
|
||||
private static boolean needAtLeastOneAttribute(XmlTag tag) {
|
||||
for (XmlTagRuleProvider ruleProvider : XmlTagRuleProvider.EP_NAME.getExtensionList()) {
|
||||
for (XmlTagRuleProvider.Rule rule : ruleProvider.getTagRule(tag)) {
|
||||
if (rule.needAtLeastOneAttribute(tag)) {
|
||||
@@ -352,7 +360,8 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
|
||||
}
|
||||
|
||||
private static void completeTagTail(Template template, XmlElementDescriptor descriptor, PsiFile file, XmlTag context, boolean firstLevel) {
|
||||
boolean completeIt = !firstLevel || !canHaveAttributes(descriptor, context);
|
||||
boolean completeIt = (!firstLevel || !canHaveAttributes(descriptor, context))
|
||||
&& (file == null || XmlExtension.getExtension(file).shouldCompleteTag(context));
|
||||
switch (descriptor.getContentType()) {
|
||||
case XmlElementDescriptor.CONTENT_TYPE_UNKNOWN:
|
||||
return;
|
||||
@@ -385,6 +394,11 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasOwnAttributes(XmlElementDescriptor descriptor, XmlTag tag) {
|
||||
return ContainerUtil.find(descriptor.getAttributesDescriptors(tag),
|
||||
attr -> attr instanceof HtmlAttributeDescriptorImpl && HtmlUtil.isOwnHtmlAttribute(attr)) != null;
|
||||
}
|
||||
|
||||
private static boolean canHaveAttributes(XmlElementDescriptor descriptor, XmlTag context) {
|
||||
XmlAttributeDescriptor[] attributes = descriptor.getAttributesDescriptors(context);
|
||||
int required = WebEditorOptions.getInstance().isAutomaticallyInsertRequiredAttributes() ?
|
||||
|
||||
@@ -170,6 +170,10 @@ public abstract class XmlExtension {
|
||||
public boolean shouldBeInserted(final XmlAttributeDescriptor descriptor) {
|
||||
return descriptor.isRequired();
|
||||
}
|
||||
|
||||
public boolean shouldCompleteTag(XmlTag context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public AttributeValuePresentation getAttributeValuePresentation(@Nullable XmlTag tag,
|
||||
|
||||
@@ -466,7 +466,9 @@ public class HtmlUtil {
|
||||
final PsiElement declaration = descriptor.getDeclaration();
|
||||
final PsiFile file = declaration != null ? declaration.getContainingFile() : null;
|
||||
final String name = file != null ? file.getName() : null;
|
||||
return "meta.rnc".equals(name);
|
||||
return "meta.rnc".equals(name) || "web-forms.rnc".equals(name)
|
||||
|| "embed.rnc".equals(name) || "tables.rnc".equals(name)
|
||||
|| "media.rnc".equals(name);
|
||||
}
|
||||
|
||||
private static class TerminateException extends RuntimeException {
|
||||
@@ -491,7 +493,7 @@ public class HtmlUtil {
|
||||
new HtmlBuilderDriver(content).build(new XmlBuilder() {
|
||||
@NonNls final Set<String> inTag = new THashSet<>();
|
||||
boolean metHttpEquiv;
|
||||
boolean metHttml5Charset;
|
||||
boolean metHtml5Charset;
|
||||
|
||||
@Override
|
||||
public void doctype(@Nullable final CharSequence publicId,
|
||||
@@ -516,7 +518,7 @@ public class HtmlUtil {
|
||||
@Override
|
||||
public void endTag(final CharSequence localName, final String namespace, final int startoffset, final int endoffset) {
|
||||
@NonNls final String name = StringUtil.toLowerCase(localName.toString());
|
||||
if ("meta".equals(name) && (metHttpEquiv || metHttml5Charset) && contentAttributeValue != null) {
|
||||
if ("meta".equals(name) && (metHttpEquiv || metHtml5Charset) && contentAttributeValue != null) {
|
||||
String charsetName;
|
||||
if (metHttpEquiv) {
|
||||
int start = contentAttributeValue.indexOf(CHARSET_PREFIX);
|
||||
@@ -537,7 +539,7 @@ public class HtmlUtil {
|
||||
}
|
||||
inTag.remove(name);
|
||||
metHttpEquiv = false;
|
||||
metHttml5Charset = false;
|
||||
metHtml5Charset = false;
|
||||
contentAttributeValue = null;
|
||||
}
|
||||
|
||||
@@ -552,7 +554,7 @@ public class HtmlUtil {
|
||||
metHttpEquiv |= value.equals("content-type");
|
||||
}
|
||||
else if (name.equals(CHARSET)) {
|
||||
metHttml5Charset = true;
|
||||
metHtml5Charset = true;
|
||||
contentAttributeValue = value;
|
||||
}
|
||||
if (name.equals("content")) {
|
||||
|
||||
Reference in New Issue
Block a user