diff --git a/README.md b/README.md index 7f3bb8d..084dd3e 100644 --- a/README.md +++ b/README.md @@ -456,7 +456,7 @@ options: * xml-deprecated-qweb-directive - https://github.com/OCA/odoo-pre-commit-hooks/blob/v0.2.20/test_repo/test_module/website_templates.xml#L7 Deprecated QWeb directive `t-esc-options`. Use `t-options` instead - - https://github.com/OCA/odoo-pre-commit-hooks/blob/v0.2.20/test_repo/test_module/website_templates.xml#L37 Deprecated QWeb directive `t-field-options`. Use `t-options` instead + - https://github.com/OCA/odoo-pre-commit-hooks/blob/v0.2.20/test_repo/test_module/website_templates.xml#L55 Deprecated QWeb directive `t-field-options`. Use `t-options` instead * xml-deprecated-qweb-directive-15 @@ -523,14 +523,14 @@ options: * xml-not-valid-char-link - - https://github.com/OCA/odoo-pre-commit-hooks/blob/v0.2.20/test_repo/test_module/website_templates.xml#L59 The resource in in src/href contains a not valid character - - https://github.com/OCA/odoo-pre-commit-hooks/blob/v0.2.20/test_repo/test_module/website_templates.xml#L61 The resource in in src/href contains a not valid character + - https://github.com/OCA/odoo-pre-commit-hooks/blob/v0.2.20/test_repo/test_module/website_templates.xml#L77 The resource in in src/href contains a not valid character + - https://github.com/OCA/odoo-pre-commit-hooks/blob/v0.2.20/test_repo/test_module/website_templates.xml#L79 The resource in in src/href contains a not valid character * xml-oe-structure-missing-id - https://github.com/OCA/odoo-pre-commit-hooks/blob/v0.2.20/test_repo/test_module/website_templates.xml#L9 Consider removing the class `oe_structure` or adding a proper id to the tag. The id must contain `oe_structure` - https://github.com/OCA/odoo-pre-commit-hooks/blob/v0.2.20/test_repo/test_module/website_templates.xml#L13 Consider removing the class `oe_structure` or adding a proper id to the tag. The id must contain `oe_structure` - - https://github.com/OCA/odoo-pre-commit-hooks/blob/v0.2.20/test_repo/test_module/website_templates.xml#L41 Consider removing the class `oe_structure` or adding a proper id to the tag. The id must contain `oe_structure` + - https://github.com/OCA/odoo-pre-commit-hooks/blob/v0.2.20/test_repo/test_module/website_templates.xml#L59 Consider removing the class `oe_structure` or adding a proper id to the tag. The id must contain `oe_structure` * xml-record-missing-id @@ -543,6 +543,12 @@ options: - https://github.com/OCA/odoo-pre-commit-hooks/blob/v0.2.20/test_repo/broken_module/model_view_odoo2.xml#L158 Redundant module name `` (move attribute to parent) or using 'style' attribute instead of tag e.g. Black Text... instead of ` (move attribute to parent) or using 'style' attribute instead of tag e.g. Black Text... instead of ` (move attribute to parent) or using 'style' attribute instead of tag e.g. Black Text... instead of <{node_textarea_child.tag} {found_attr}=...` " - "incompatible for Prettier XML auto-fix. To prevent unexpected text insertion " - f"prefer `<{node_textarea.tag} {found_attr}=...`" - ), - filepath=manifest_data["filename_short"], - line=node_textarea_child.sourceline, - ) - # TODO: Autofix using the same node + # Tags that wrap inline content and are affected by prettier formatting + inline_wrapper_tags = {"textarea", "b", "strong", "i", "em", "span", "a", "u", "s", "small", "mark"} + + for wrapper_tag in inline_wrapper_tags: + for node_wrapper in template.xpath(f".//{wrapper_tag}"): + children = node_wrapper.getchildren() + if len(children) != 1: + continue + + node_wrapper_child = children[0] + + # Check if child has template attributes + found_attr = set(node_wrapper_child.attrib) & target_attrs + if not found_attr: + continue + + # Only check for t or span tags with template attributes + if node_wrapper_child.tag not in ("t", "span"): + continue + + # Check if wrapper has ONLY whitespace (or nothing) before the child + wrapper_text = node_wrapper.text or "" + has_meaningful_text = wrapper_text.strip() + + # The problem occurs when: + # 1. There's a template attribute on the child + # 2. The wrapper has no meaningful text before the child (only whitespace/newlines) + # This means prettier will reformat and add unwanted newlines + if not has_meaningful_text: + found_attr = found_attr.pop() + self.register_error( + code="xml-template-prettier-incompatible", + message=( + f"Node `<{node_wrapper.tag} ...><{node_wrapper_child.tag} {found_attr}=...` " + "incompatible for Prettier XML auto-fix. To prevent unexpected text insertion " + f"prefer `<{node_wrapper.tag} {found_attr}=...>` (move attribute to parent) or " + "using 'style' attribute instead of tag " + 'e.g. Black Text... instead of bool: """Check if filename contains escaped double quotes " -> " @@ -765,6 +787,7 @@ def check_xml_double_quotes_py(self): "xml-dangerous-qweb-replace-low-priority", "xml-duplicate-template-id", "xml-id-position-first", + "xml-superfluous-attributeless", "xml-template-prettier-incompatible", ) def check_xml_templates(self): @@ -778,6 +801,7 @@ def check_xml_templates(self): Indentify nodes incompatible with Prettier XML auto-fix generating possible unexpected text insertion """ template_ids: Dict[str, List[FileElementPair]] = defaultdict(list) + pattern = re.compile(rb"(.*?)") for manifest_data in self.manifest_datas: for template in self.xpath_template(manifest_data["node"]): if self.is_message_enabled( @@ -789,6 +813,25 @@ def check_xml_templates(self): if not template_id: # pragma: no cover continue template_ids[template_id].append(FileElementPair(manifest_data["filename_short"], template)) + if self.is_message_enabled("xml-superfluous-attributeless", manifest_data["disabled_checks"]): + for node_attrless in template.xpath(".//span[not(@*)]"): + self.register_error( + code="xml-superfluous-attributeless", + message=f"Remove superfluous attributeless `<{node_attrless.tag}`", + info=f"Serve no purpose and cause formatting inconsistencies with Prettier", + filepath=manifest_data["filename_short"], + line=node_attrless.sourceline, + ) + if self.autofix: + node_content = node_xml.NodeContent(manifest_data["filename"], node_attrless) + new_content_node = pattern.sub(rb"\1", node_content.content_node, count=1) + if new_content_node != node_content.content_node: + # Modify the record attrib to propagate the change to other checks + node_content.content_node = new_content_node + utils.perform_fix(manifest_data["filename"], bytes(node_content)) + # TODO: check if the "for" affects updating the nodes + self.update_node(manifest_data) # update sourceline after delete a node + if self.is_message_enabled("xml-template-prettier-incompatible", manifest_data["disabled_checks"]): self.verify_template_prettier_incompatible(template, manifest_data) diff --git a/test_repo/test_module/website_templates.xml b/test_repo/test_module/website_templates.xml index f118dbd..55592ee 100644 --- a/test_repo/test_module/website_templates.xml +++ b/test_repo/test_module/website_templates.xml @@ -28,6 +28,24 @@ + +
+
+ Dear + + + :
+ By this means, you are informed that the budget movement of + + with the number: + + + + has been liquidated and transferred + to the available balance of the related budgetary item.
+ Regards, +
+
diff --git a/tests/test_checks.py b/tests/test_checks.py index 65a413a..edf8ae8 100644 --- a/tests/test_checks.py +++ b/tests/test_checks.py @@ -44,7 +44,7 @@ "xml-not-valid-char-link": 2, "xml-redundant-module-name": 3, "xml-syntax-error": 2, - "xml-template-prettier-incompatible": 3, + "xml-template-prettier-incompatible": 5, "xml-view-dangerous-replace-low-priority": 7, "xml-xpath-translatable-item": 4, "xml-oe-structure-missing-id": 6, @@ -56,6 +56,7 @@ "xml-deprecated-oe-chatter": 1, "xml-field-bool-without-eval": 2, "xml-field-numeric-without-eval": 7, + "xml-superfluous-attributeless": 5, }