From 5c73467c475a0ce00bef73f5614e2bc4600bcdfd Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Tue, 25 Jul 2017 13:51:38 +0300 Subject: [PATCH] WEB-26468 Emmet in JSX, support non-self closing tags for host components --- .../template/emmet/EmmetParser.java | 2 +- .../template/emmet/XmlEmmetParser.java | 20 +++++++++++++------ .../generators/XmlZenCodingGenerator.java | 4 ++-- .../emmet/generators/ZenCodingGenerator.java | 4 ++-- .../template/emmet/nodes/TemplateNode.java | 6 +++--- .../template/emmet/tokens/TemplateToken.java | 16 ++++++++++++--- 6 files changed, 35 insertions(+), 17 deletions(-) diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetParser.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetParser.java index e793f6e6fda2..0ddb4d95bd86 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetParser.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetParser.java @@ -202,7 +202,7 @@ public abstract class EmmetParser { protected boolean setTemplate(final TemplateToken token, TemplateImpl template) { if (template == null) { - template = myGenerator.createTemplateByKey(token.getKey()); + template = myGenerator.createTemplateByKey(token.getKey(), token.isForceSingleTag()); } if (template == null) { return false; diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/XmlEmmetParser.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/XmlEmmetParser.java index e2dd5d0eec24..78b06c0cab24 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/XmlEmmetParser.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/XmlEmmetParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,10 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -170,17 +173,22 @@ public class XmlEmmetParser extends EmmetParser { return null; } + boolean forceSingleTag = false; TemplateImpl template = myCallback.findApplicableTemplate(templateKey); + if (template == null && StringUtil.endsWithChar(templateKey, '/')) { + forceSingleTag = true; + templateKey = StringUtil.trimEnd(templateKey, '/'); + } if (template == null && !ZenCodingUtil.isXML11ValidQName(templateKey) && !StringUtil.containsChar(templateKey, '$')) { return null; } - final Map attributes = parseSelectors(); + Map attributes = parseSelectors(); if (mustHaveSelector && attributes.isEmpty()) { return null; } - final TemplateToken templateToken = new TemplateToken(templateKey, attributes); + TemplateToken templateToken = new TemplateToken(templateKey, attributes, forceSingleTag); if (!setTemplate(templateToken, template)) { return null; } @@ -310,7 +318,7 @@ public class XmlEmmetParser extends EmmetParser { if (token == ZenCodingTokens.OPENING_SQ_BRACKET) { advance(); final List> attrList = parseAttributeList(); - if (attrList == null || getToken() != ZenCodingTokens.CLOSING_SQ_BRACKET) { + if (getToken() != ZenCodingTokens.CLOSING_SQ_BRACKET) { return null; } advance(); @@ -336,7 +344,7 @@ public class XmlEmmetParser extends EmmetParser { return HtmlUtil.CLASS_ATTRIBUTE_NAME; } - @Nullable + @NotNull private List> parseAttributeList() { final List> result = new ArrayList<>(); while (true) { diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGenerator.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGenerator.java index 32544986430f..d7be76da1ad2 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGenerator.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/XmlZenCodingGenerator.java @@ -54,10 +54,10 @@ public abstract class XmlZenCodingGenerator extends ZenCodingGenerator { } @Override - public TemplateImpl createTemplateByKey(@NotNull String key) { + public TemplateImpl createTemplateByKey(@NotNull String key, boolean forceSingleTag) { StringBuilder builder = new StringBuilder("<"); builder.append(key).append('>'); - if (!HtmlUtil.isSingleHtmlTag(key)) { + if (!forceSingleTag && !HtmlUtil.isSingleHtmlTag(key)) { builder.append("$END$'); } return new TemplateImpl("", builder.toString(), ""); diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/ZenCodingGenerator.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/ZenCodingGenerator.java index 2321c94ec6ee..467536caea26 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/ZenCodingGenerator.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/ZenCodingGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,7 @@ public abstract class ZenCodingGenerator { public abstract TemplateImpl generateTemplate(@NotNull TemplateToken token, boolean hasChildren, @NotNull PsiElement context); @Nullable - public TemplateImpl createTemplateByKey(@NotNull String key) { + public TemplateImpl createTemplateByKey(@NotNull String key, boolean forceSingleTag) { return null; } diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/TemplateNode.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/TemplateNode.java index e278643b47ff..e694f70e6960 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/TemplateNode.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/TemplateNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,8 +56,8 @@ public class TemplateNode extends ZenCodingNode { String templateKey = templateToken.getKey(); if (myGenerator != null && StringUtil.containsChar(templateKey, '$') && callback.findApplicableTemplate(templateKey) == null) { String newTemplateKey = ZenCodingUtil.replaceMarkers(templateKey, numberInIteration, totalIterations, surroundedText); - TemplateToken newTemplateToken = new TemplateToken(newTemplateKey, templateToken.getAttributes()); - TemplateImpl template = myGenerator.createTemplateByKey(newTemplateKey); + TemplateToken newTemplateToken = new TemplateToken(newTemplateKey, templateToken.getAttributes(), templateToken.isForceSingleTag()); + TemplateImpl template = myGenerator.createTemplateByKey(newTemplateKey, newTemplateToken.isForceSingleTag()); if (template != null) { template.setDeactivated(true); newTemplateToken.setTemplate(template, callback); diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/tokens/TemplateToken.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/tokens/TemplateToken.java index 5b52083fa588..ce4d2c758dfd 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/tokens/TemplateToken.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/tokens/TemplateToken.java @@ -40,15 +40,21 @@ public class TemplateToken extends ZenCodingToken { @NotNull private final String myKey; private TemplateImpl myTemplate; @NotNull private final Map myAttributes; - private PsiFile myFile; + private final boolean myForceSingleTag; + private PsiFile myFile; public TemplateToken(@NotNull String key) { this(key, Collections.emptyMap()); } public TemplateToken(@NotNull String key, @NotNull Map attribute2value) { + this(key, attribute2value, false); + } + + public TemplateToken(@NotNull String key, @NotNull Map attribute2value, boolean forceSingleTag) { myKey = key; myAttributes = attribute2value; + myForceSingleTag = forceSingleTag; } @NotNull @@ -59,7 +65,7 @@ public class TemplateToken extends ZenCodingToken { public PsiFile getFile() { return myFile; } - + public String getTemplateText() { return myFile.getText(); } @@ -67,7 +73,11 @@ public class TemplateToken extends ZenCodingToken { private void setFile(PsiFile file) { myFile = file; } - + + public boolean isForceSingleTag() { + return myForceSingleTag; + } + @Nullable public XmlTag getXmlTag() { return PsiTreeUtil.findChildOfType(myFile, XmlTag.class);