diff --git a/xml/impl/src/com/intellij/psi/formatter/MarkupLineWrapPositionStrategy.java b/xml/impl/src/com/intellij/psi/formatter/MarkupLineWrapPositionStrategy.java
index 27ebf3d3d4a5..3d35e35e2022 100644
--- a/xml/impl/src/com/intellij/psi/formatter/MarkupLineWrapPositionStrategy.java
+++ b/xml/impl/src/com/intellij/psi/formatter/MarkupLineWrapPositionStrategy.java
@@ -15,18 +15,44 @@
*/
package com.intellij.psi.formatter;
-import com.intellij.openapi.editor.LineWrapPositionStrategy;
-import com.intellij.openapi.editor.PsiAwareDefaultLineWrapPositionStrategy;
+import com.intellij.openapi.editor.*;
+import com.intellij.openapi.project.Project;
import com.intellij.psi.TokenType;
import com.intellij.psi.xml.XmlElementType;
import com.intellij.psi.xml.XmlTokenType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* {@link LineWrapPositionStrategy} for markup languages like XML, HTML etc.
*/
public class MarkupLineWrapPositionStrategy extends PsiAwareDefaultLineWrapPositionStrategy {
+ private final DefaultLineWrapPositionStrategy myDefaultStrategy = new DefaultLineWrapPositionStrategy();
+
public MarkupLineWrapPositionStrategy() {
super(true, XmlElementType.XML_TEXT, XmlElementType.HTML_RAW_TEXT, XmlTokenType.XML_COMMENT_CHARACTERS, TokenType.WHITE_SPACE);
+
+ myDefaultStrategy.addRule(new GenericLineWrapPositionStrategy.Rule('<', GenericLineWrapPositionStrategy.WrapCondition.BEFORE));
+ myDefaultStrategy.addRule(new GenericLineWrapPositionStrategy.Rule('/', GenericLineWrapPositionStrategy.WrapCondition.AFTER,
+ GenericLineWrapPositionStrategy.Rule.DEFAULT_WEIGHT - 2));
+ }
+
+ @Override
+ public int calculateWrapPosition(@NotNull Document document,
+ @Nullable Project project,
+ int startOffset,
+ int endOffset,
+ int maxPreferredOffset,
+ boolean allowToBeyondMaxPreferredOffset,
+ boolean isSoftWrap) {
+ if (isSoftWrap) {
+ return myDefaultStrategy.calculateWrapPosition(
+ document, project, startOffset, endOffset, maxPreferredOffset, allowToBeyondMaxPreferredOffset, isSoftWrap);
+ }
+ else {
+ return super.calculateWrapPosition(
+ document, project, startOffset, endOffset, maxPreferredOffset, allowToBeyondMaxPreferredOffset, isSoftWrap);
+ }
}
}
diff --git a/xml/tests/src/com/intellij/psi/formatter/HtmlLineWrapPositionStrategyTest.kt b/xml/tests/src/com/intellij/psi/formatter/HtmlLineWrapPositionStrategyTest.kt
new file mode 100644
index 000000000000..3427203ea618
--- /dev/null
+++ b/xml/tests/src/com/intellij/psi/formatter/HtmlLineWrapPositionStrategyTest.kt
@@ -0,0 +1,49 @@
+// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.psi.formatter
+
+import com.intellij.openapi.editor.AbstractLineWrapPositionStrategyTest
+import com.intellij.openapi.editor.LineWrapPositionStrategy
+import org.junit.Before
+import org.junit.Test
+
+class HtmlLineWrapPositionStrategyTest : AbstractLineWrapPositionStrategyTest() {
+
+ private lateinit var myStrategy: LineWrapPositionStrategy
+
+ @Before
+ override fun prepare() {
+ super.prepare()
+ myStrategy = MarkupLineWrapPositionStrategy()
+ }
+
+ @Test
+ fun doNotWrapWithinClosingTagStart1() {
+ doTest(myStrategy,
+ ">")
+ }
+
+ @Test
+ fun doNotWrapWithinClosingTagStart2() {
+ doTest(myStrategy,
+ "a>")
+ }
+
+ @Test
+ fun doNotWrapWithinClosingTagStart3() {
+ doTest(myStrategy,
+ "</a>")
+ }
+
+ @Test
+ fun doNotWrapWithinClosingTagStart4() {
+ doTest(myStrategy,
+ "")
+ }
+
+ @Test
+ fun wrapAfterSlash() {
+ val document =
+ "MUIFAHGA2fUufYYM4ynBfdgdfgdsfffffffffffffff5Bc\">"
+ doTest(myStrategy, document)
+ }
+}
\ No newline at end of file