blob: 2f8c47a710b16951b9dcd22f8f67ede08f9bbf90 [file] [log] [blame]
/*
* Copyright 2000-2014 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.lang.xml;
import com.intellij.lang.ASTFactory;
import com.intellij.lang.ASTNode;
import com.intellij.psi.formatter.WhiteSpaceFormattingStrategyAdapter;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.impl.source.tree.Factory;
import com.intellij.psi.impl.source.tree.LeafElement;
import com.intellij.psi.impl.source.tree.SharedImplUtil;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.xml.XmlElementType;
import com.intellij.psi.xml.XmlText;
import com.intellij.psi.xml.XmlTokenType;
import com.intellij.util.CharTable;
import org.jetbrains.annotations.NotNull;
/**
* @author Denis Zhdanov
* @since 12/6/11 4:51 PM
*/
public class XmlWhiteSpaceFormattingStrategy extends WhiteSpaceFormattingStrategyAdapter {
private static void addWhitespaceToTagBody(final ASTNode treePrev, final LeafElement whiteSpaceElement) {
final CharTable charTable = SharedImplUtil.findCharTableByTree(treePrev);
final ASTNode treeParent = treePrev.getTreeParent();
final boolean before;
final XmlText xmlText;
if(treePrev.getElementType() == XmlElementType.XML_TEXT) {
xmlText = (XmlText)treePrev.getPsi();
before = true;
}
else if(treePrev.getTreePrev().getElementType() == XmlElementType.XML_TEXT){
xmlText = (XmlText)treePrev.getTreePrev().getPsi();
before = false;
}
else{
xmlText = (XmlText)Factory.createCompositeElement(XmlElementType.XML_TEXT, charTable, treeParent.getPsi().getManager());
CodeEditUtil.setNodeGenerated(xmlText.getNode(), true);
treeParent.addChild(xmlText.getNode(), treePrev);
before = true;
}
final ASTNode node = xmlText.getNode();
assert node != null;
final TreeElement anchorInText = (TreeElement) (before ? node.getFirstChildNode() : node.getLastChildNode());
if (anchorInText == null) node.addChild(whiteSpaceElement);
else if (anchorInText.getElementType() != XmlTokenType.XML_WHITE_SPACE) node.addChild(whiteSpaceElement, before ? anchorInText : null);
else {
final String text = before ? whiteSpaceElement.getText() + anchorInText.getText() : anchorInText.getText() +
whiteSpaceElement.getText();
node.replaceChild(anchorInText, ASTFactory.whitespace(text));
}
}
protected boolean isInsideTagBody(@NotNull ASTNode place) {
final ASTNode treeParent = place.getTreeParent();
if(treeParent.getElementType() != XmlElementType.XML_TAG
&& treeParent.getElementType() != XmlElementType.HTML_TAG) return false;
while(place != null){
if(place.getElementType() == XmlTokenType.XML_TAG_END) return true;
place = place.getTreePrev();
}
return false;
}
@Override
public boolean addWhitespace(@NotNull final ASTNode treePrev, @NotNull final LeafElement whiteSpaceElement) {
if (isInsideTagBody(treePrev)) {
addWhitespaceToTagBody(treePrev, whiteSpaceElement);
return true;
}
return false;
}
@Override
public boolean containsWhitespacesOnly(@NotNull final ASTNode node) {
return (node.getElementType() == XmlTokenType.XML_DATA_CHARACTERS) &&
node.getText().trim().length() == 0;
}
}