mirror of
https://github.com/bringout/oca-ocb-core.git
synced 2026-04-20 04:12:02 +02:00
18.0 vanilla
This commit is contained in:
parent
d72e748793
commit
0a7ae8db93
337 changed files with 399651 additions and 232598 deletions
|
|
@ -1,18 +1,25 @@
|
|||
|
||||
from lxml import etree
|
||||
from lxml.builder import E
|
||||
import copy
|
||||
import itertools
|
||||
import logging
|
||||
import re
|
||||
|
||||
from odoo.tools.translate import _
|
||||
from odoo.tools import SKIPPED_ELEMENT_TYPES, html_escape
|
||||
from odoo.exceptions import ValidationError
|
||||
from lxml import etree
|
||||
from lxml.builder import E
|
||||
|
||||
from odoo.tools.translate import LazyTranslate
|
||||
from odoo.exceptions import ValidationError
|
||||
from .misc import SKIPPED_ELEMENT_TYPES, html_escape
|
||||
|
||||
__all__ = []
|
||||
|
||||
_lt = LazyTranslate('base')
|
||||
_logger = logging.getLogger(__name__)
|
||||
RSTRIP_REGEXP = re.compile(r'\n[ \t]*$')
|
||||
|
||||
# attribute names that contain Python expressions
|
||||
PYTHON_ATTRIBUTES = {'readonly', 'required', 'invisible', 'column_invisible', 't-if', 't-elif'}
|
||||
|
||||
|
||||
def add_stripped_items_before(node, spec, extract):
|
||||
text = spec.text or ''
|
||||
|
||||
|
|
@ -36,7 +43,9 @@ def add_stripped_items_before(node, spec, extract):
|
|||
|
||||
for child in spec:
|
||||
if child.get('position') == 'move':
|
||||
tail = child.tail
|
||||
child = extract(child)
|
||||
child.tail = tail
|
||||
node.addprevious(child)
|
||||
|
||||
|
||||
|
|
@ -77,7 +86,7 @@ def locate_node(arch, spec):
|
|||
try:
|
||||
xPath = etree.ETXPath(expr)
|
||||
except etree.XPathSyntaxError as e:
|
||||
raise ValidationError(_("Invalid Expression while parsing xpath %r", expr)) from e
|
||||
raise ValidationError(_lt("Invalid Expression while parsing xpath “%s”", expr)) from e
|
||||
nodes = xPath(arch)
|
||||
return nodes[0] if nodes else None
|
||||
elif spec.tag == 'field':
|
||||
|
|
@ -122,7 +131,7 @@ def apply_inheritance_specs(source, specs_tree, inherit_branding=False, pre_loca
|
|||
"""
|
||||
if len(spec):
|
||||
raise ValueError(
|
||||
_("Invalid specification for moved nodes: %r", etree.tostring(spec, encoding='unicode'))
|
||||
_lt("Invalid specification for moved nodes: “%s”", etree.tostring(spec, encoding='unicode'))
|
||||
)
|
||||
pre_locate(spec)
|
||||
to_extract = locate_node(source, spec)
|
||||
|
|
@ -131,7 +140,7 @@ def apply_inheritance_specs(source, specs_tree, inherit_branding=False, pre_loca
|
|||
return to_extract
|
||||
else:
|
||||
raise ValueError(
|
||||
_("Element %r cannot be located in parent view", etree.tostring(spec, encoding='unicode'))
|
||||
_lt("Element “%s” cannot be located in parent view", etree.tostring(spec, encoding='unicode'))
|
||||
)
|
||||
|
||||
while len(specs):
|
||||
|
|
@ -210,26 +219,80 @@ def apply_inheritance_specs(source, specs_tree, inherit_branding=False, pre_loca
|
|||
node.text = spec.text
|
||||
|
||||
else:
|
||||
raise ValueError(_("Invalid mode attribute:") + " '%s'" % mode)
|
||||
raise ValueError(_lt("Invalid mode attribute: “%s”", mode))
|
||||
elif pos == 'attributes':
|
||||
for child in spec.getiterator('attribute'):
|
||||
attribute = child.get('name')
|
||||
value = child.text or ''
|
||||
if child.get('add') or child.get('remove'):
|
||||
assert not child.text
|
||||
separator = child.get('separator', ',')
|
||||
if separator == ' ':
|
||||
separator = None # squash spaces
|
||||
to_add = (
|
||||
s for s in (s.strip() for s in child.get('add', '').split(separator))
|
||||
if s
|
||||
)
|
||||
to_remove = {s.strip() for s in child.get('remove', '').split(separator)}
|
||||
values = (s.strip() for s in node.get(attribute, '').split(separator))
|
||||
value = (separator or ' ').join(itertools.chain(
|
||||
(v for v in values if v not in to_remove),
|
||||
to_add
|
||||
# The element should only have attributes:
|
||||
# - name (mandatory),
|
||||
# - add, remove, separator
|
||||
# - any attribute that starts with data-oe-*
|
||||
unknown = [
|
||||
key
|
||||
for key in child.attrib
|
||||
if key not in ('name', 'add', 'remove', 'separator')
|
||||
and not key.startswith('data-oe-')
|
||||
]
|
||||
if unknown:
|
||||
raise ValueError(_lt(
|
||||
"Invalid attributes %s in element <attribute>",
|
||||
", ".join(map(repr, unknown)),
|
||||
))
|
||||
|
||||
attribute = child.get('name')
|
||||
value = None
|
||||
|
||||
if child.get('add') or child.get('remove'):
|
||||
if child.text:
|
||||
raise ValueError(_lt(
|
||||
"Element <attribute> with 'add' or 'remove' cannot contain text %s",
|
||||
repr(child.text),
|
||||
))
|
||||
value = node.get(attribute, '')
|
||||
add = child.get('add', '')
|
||||
remove = child.get('remove', '')
|
||||
separator = child.get('separator')
|
||||
|
||||
if attribute in PYTHON_ATTRIBUTES or attribute.startswith('decoration-'):
|
||||
# attribute containing a python expression
|
||||
separator = separator.strip()
|
||||
if separator not in ('and', 'or'):
|
||||
raise ValueError(_lt(
|
||||
"Invalid separator %(separator)s for python expression %(expression)s; "
|
||||
"valid values are 'and' and 'or'",
|
||||
separator=repr(separator), expression=repr(attribute),
|
||||
))
|
||||
if remove:
|
||||
if re.match(rf'^\(*{remove}\)*$', value):
|
||||
value = ''
|
||||
else:
|
||||
patterns = [
|
||||
f"({remove}) {separator} ",
|
||||
f" {separator} ({remove})",
|
||||
f"{remove} {separator} ",
|
||||
f" {separator} {remove}",
|
||||
]
|
||||
for pattern in patterns:
|
||||
index = value.find(pattern)
|
||||
if index != -1:
|
||||
value = value[:index] + value[index + len(pattern):]
|
||||
break
|
||||
if add:
|
||||
value = f"({value}) {separator} ({add})" if value else add
|
||||
else:
|
||||
if separator is None:
|
||||
separator = ','
|
||||
elif separator == ' ':
|
||||
separator = None # squash spaces
|
||||
values = (s.strip() for s in value.split(separator))
|
||||
to_add = filter(None, (s.strip() for s in add.split(separator)))
|
||||
to_remove = {s.strip() for s in remove.split(separator)}
|
||||
value = (separator or ' ').join(itertools.chain(
|
||||
(v for v in values if v and v not in to_remove),
|
||||
to_add
|
||||
))
|
||||
else:
|
||||
value = child.text or ''
|
||||
|
||||
if value:
|
||||
node.set(attribute, value)
|
||||
elif attribute in node.attrib:
|
||||
|
|
@ -255,10 +318,7 @@ def apply_inheritance_specs(source, specs_tree, inherit_branding=False, pre_loca
|
|||
add_stripped_items_before(node, spec, extract)
|
||||
|
||||
else:
|
||||
raise ValueError(
|
||||
_("Invalid position attribute: '%s'") %
|
||||
pos
|
||||
)
|
||||
raise ValueError(_lt("Invalid position attribute: '%s'", pos))
|
||||
|
||||
else:
|
||||
attrs = ''.join([
|
||||
|
|
@ -268,7 +328,7 @@ def apply_inheritance_specs(source, specs_tree, inherit_branding=False, pre_loca
|
|||
])
|
||||
tag = "<%s%s>" % (spec.tag, attrs)
|
||||
raise ValueError(
|
||||
_("Element '%s' cannot be located in parent view", tag)
|
||||
_lt("Element '%s' cannot be located in parent view", tag)
|
||||
)
|
||||
|
||||
return source
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue