Skip to content

Commit 98c84d1

Browse files
authored
[T3CMS] Add Inspection with QuickFix for data-namespace-typo3-fluid (#334)
1 parent a77bd53 commit 98c84d1

File tree

7 files changed

+174
-1
lines changed

7 files changed

+174
-1
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.cedricziel.idea.typo3.codeInspection;
2+
3+
import com.intellij.codeInspection.LocalInspectionTool;
4+
import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
5+
import com.intellij.codeInspection.ProblemsHolder;
6+
import com.intellij.codeInspection.util.IntentionFamilyName;
7+
import com.intellij.codeInspection.util.IntentionName;
8+
import com.intellij.openapi.project.Project;
9+
import com.intellij.psi.*;
10+
import com.intellij.psi.xml.XmlAttribute;
11+
import com.intellij.psi.xml.XmlTag;
12+
import org.jetbrains.annotations.NotNull;
13+
14+
public class FluidNamespaceWithoutDataAttributeInspection extends LocalInspectionTool {
15+
16+
public static final String DATA_NAMESPACE_TYPO_3_FLUID = "data-namespace-typo3-fluid";
17+
18+
/**
19+
* Override to provide your own inspection visitor.
20+
* Created visitor must not be recursive (e.g. it must not inherit {@link PsiRecursiveElementVisitor})
21+
* since it will be fed with every element in the file anyway.
22+
* Visitor created must be thread-safe since it might be called on several elements concurrently.
23+
*
24+
* @param holder where visitor will register problems found.
25+
* @param isOnTheFly true if inspection was run in non-batch mode
26+
* @return not-null visitor for this inspection.
27+
* @see PsiRecursiveVisitor
28+
*/
29+
@Override
30+
public @NotNull PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
31+
return new XmlElementVisitor() {
32+
@Override
33+
public void visitElement(@NotNull PsiElement element) {
34+
if (element instanceof XmlTag) {
35+
this.visitXmlTag((XmlTag) element);
36+
}
37+
38+
super.visitElement(element);
39+
}
40+
41+
@Override
42+
public void visitXmlTag(XmlTag tag) {
43+
final boolean hasRequiredDataAttribute = tag.getAttribute(DATA_NAMESPACE_TYPO_3_FLUID) != null;
44+
boolean needsRequiredDataAttribute = false;
45+
for (XmlAttribute attribute : tag.getAttributes()) {
46+
if (!attribute.isNamespaceDeclaration()) {
47+
continue;
48+
}
49+
50+
if (attribute.getValue() == null || !attribute.getValue().contains("typo3.org/ns")) {
51+
continue;
52+
}
53+
54+
if (!tag.getName().equals("html") && !hasRequiredDataAttribute) {
55+
needsRequiredDataAttribute = true;
56+
57+
break;
58+
}
59+
}
60+
61+
if (needsRequiredDataAttribute) {
62+
holder.registerProblem(tag, "Fluid data-attribute missing", new AddFluidNamespaceDataAttributeFix(tag));
63+
}
64+
}
65+
};
66+
}
67+
68+
public static class AddFluidNamespaceDataAttributeFix extends LocalQuickFixOnPsiElement {
69+
protected AddFluidNamespaceDataAttributeFix(@NotNull XmlTag element) {
70+
super(element);
71+
}
72+
73+
@Override
74+
public @NotNull @IntentionName String getText() {
75+
return "Add fluid data attribute";
76+
}
77+
78+
@Override
79+
public void invoke(@NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement) {
80+
XmlTag tag = (XmlTag) startElement;
81+
82+
tag.setAttribute(DATA_NAMESPACE_TYPO_3_FLUID, "true");
83+
}
84+
85+
/**
86+
* @return text to appear in "Apply Fix" popup when multiple Quick Fixes exist (in the results of batch code inspection). For example,
87+
* if the name of the quickfix is "Create template <filename&gt", the return value of getFamilyName() should be "Create template".
88+
* If the name of the quickfix does not depend on a specific element, simply return {@link #getName()}.
89+
*/
90+
@Override
91+
public @NotNull @IntentionFamilyName String getFamilyName() {
92+
return "Add fluid data attribute";
93+
}
94+
}
95+
96+
}

typo3-cms/src/main/resources/META-INF/plugin.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
</change-notes>
1717

1818
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
19-
<idea-version since-build="193"/>
19+
<idea-version since-build="202"/>
2020

2121
<depends>com.intellij.modules.platform</depends>
2222
<depends>com.jetbrains.php</depends>
@@ -195,6 +195,12 @@
195195
<lang.inspectionSuppressor language="XHTML"
196196
implementationClass="com.cedricziel.idea.typo3.codeInspection.XmlUnusedNamespaceDeclarationSuppressor"/>
197197
<implicitUsageProvider implementation="com.cedricziel.idea.typo3.codeInspection.daemon.XmlNamespaceImplicitUsageProvider"/>
198+
<localInspection implementationClass="com.cedricziel.idea.typo3.codeInspection.FluidNamespaceWithoutDataAttributeInspection"
199+
shortName="FluidNamespaceWithoutDataAttribute"
200+
displayName="Fluid namespace declaration without data attribute"
201+
groupPath="TYPO3 CMS"
202+
groupName="Fluid templating"
203+
enabledByDefault="true" level="WARNING"/>
198204
</extensions>
199205

200206
<actions>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<html>
2+
<body>
3+
<p>Fluid can automatically remove a wrapper div
4+
when you declare a special data-attribute on it.
5+
</p>
6+
<!-- tooltip end -->
7+
<p>Add the data attribute to the tag.</p>
8+
</body>
9+
</html>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.cedricziel.idea.typo3.codeInspection;
2+
3+
import com.cedricziel.idea.typo3.AbstractTestCase;
4+
import com.intellij.codeInsight.intention.IntentionAction;
5+
6+
import java.util.List;
7+
8+
public class FluidNamespaceWithoutDataAttributeInspectionTest extends AbstractTestCase {
9+
@Override
10+
protected String getTestDataPath() {
11+
return super.getTestDataPath() + "/codeInspection";
12+
}
13+
14+
public void testMissingDataAttributeIsHighlighted() {
15+
myFixture.enableInspections(new FluidNamespaceWithoutDataAttributeInspection());
16+
17+
myFixture.testHighlighting("fluid_data_attribute_missing.html");
18+
}
19+
20+
public void testApplyingQuickFixAddsTheAttribute() {
21+
myFixture.enableInspections(new FluidNamespaceWithoutDataAttributeInspection());
22+
23+
final List<IntentionAction> allQuickFixes = myFixture.getAllQuickFixes("fluid_data_attribute_missing_fix.html");
24+
for (IntentionAction allQuickFix : allQuickFixes) {
25+
if (allQuickFix.getText().equals("Add fluid data attribute")) {
26+
myFixture.launchAction(allQuickFix);
27+
}
28+
}
29+
30+
myFixture.checkResultByFile("fluid_data_attribute_missing_fix_after.html");
31+
}
32+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<warning descr="Fluid data-attribute missing"><div xmlns="http://www.w3.org/1999/xhtml" lang="en"
2+
xmlns:v="<warning descr="URI is not registered (Settings | Languages & Frameworks | Schemas and DTDs)">http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers</warning>"
3+
xmlns:f="<warning descr="URI is not registered (Settings | Languages & Frameworks | Schemas and DTDs)">http://typo3.org/ns/TYPO3/Fluid/ViewHelpers</warning>"
4+
xmlns:flux="<warning descr="URI is not registered (Settings | Languages & Frameworks | Schemas and DTDs)">http://typo3.org/ns/FluidTYPO3/Flux/ViewHelpers</warning>"
5+
xmlns:yp="<warning descr="URI is not registered (Settings | Languages & Frameworks | Schemas and DTDs)">http://typo3.org/ns/Vendor/YourPlugin/ViewHelpers</warning>"
6+
7+
flux:schemaLocation="http://fluidtypo3.org/schemas/flux-7.0.0.xsd"
8+
v:schemaLocation="http://fluidtypo3.org/schemas/vhs-1.8.5.xsd">
9+
<!-- Fluid goes here -->
10+
</div></warning>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
2+
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
3+
xmlns:f="http://typo3.org/ns/TYPO3/Fluid/ViewHelpers"
4+
xmlns:flux="http://typo3.org/ns/FluidTYPO3/Flux/ViewHelpers"
5+
xmlns:yp="http://typo3.org/ns/Vendor/YourPlugin/ViewHelpers"
6+
7+
flux:schemaLocation="http://fluidtypo3.org/schemas/flux-7.0.0.xsd"
8+
v:schemaLocation="http://fluidtypo3.org/schemas/vhs-1.8.5.xsd">
9+
<!-- Fluid goes here -->
10+
</div>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
2+
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
3+
xmlns:f="http://typo3.org/ns/TYPO3/Fluid/ViewHelpers"
4+
xmlns:flux="http://typo3.org/ns/FluidTYPO3/Flux/ViewHelpers"
5+
xmlns:yp="http://typo3.org/ns/Vendor/YourPlugin/ViewHelpers"
6+
7+
flux:schemaLocation="http://fluidtypo3.org/schemas/flux-7.0.0.xsd"
8+
v:schemaLocation="http://fluidtypo3.org/schemas/vhs-1.8.5.xsd" data-namespace-typo3-fluid="true">
9+
<!-- Fluid goes here -->
10+
</div>

0 commit comments

Comments
 (0)