[FIX] base: fix positional branding when inherited t-field sibling
The xpath branding of a node which followed a t-field node which was
added by an inheritance view was not correct. E.g.
View 1:
```
<hello>
<world id="1"></world>
<world t-field="a"/>
<world id="2"></world>
<world id="3"></world>
</hello>
```
View 2 inheriting view 1:
```
<xpath expr="/hello/world[3]" position="after">
<world t-field="b"/>
</xpath>
```
So the result is:
```
<hello>
<world id="1"></world>
<world t-field="a"/>
<world id="2"></world>
<world t-field="b"/>
<world id="3"></world>
</hello>
```
Now the xpath branding of world id="2" was /hello[1]/world[3], which
is correct.
But the xpath branding of world id="3" was /hello[1]/world[5] which is
incorrect as it should be /hello[1]/world[4] (as related to the
original view). This was because inherited t-field did not carry any
information they came from inheritance (as "normal" nodes would).
The side effect of this was that the incorrectly marked node was not
possible to edit (and made the editor crash on save).
closes odoo/odoo#60976
X-original-commit: 07cf2b9520fc6c79a9a7ca39929bda0bfbe85e3a
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
@@ -692,7 +692,10 @@ actual arch.
|
||||
def inherit_branding(self, specs_tree):
|
||||
for node in specs_tree.iterchildren(tag=etree.Element):
|
||||
xpath = node.getroottree().getpath(node)
|
||||
if node.tag == 'data' or node.tag == 'xpath' or node.get('position') or node.get('t-field'):
|
||||
if node.get('t-field'):
|
||||
node.set('data-oe-xpath', xpath)
|
||||
self.inherit_branding(node)
|
||||
elif node.tag == 'data' or node.tag == 'xpath' or node.get('position'):
|
||||
self.inherit_branding(node)
|
||||
else:
|
||||
node.set('data-oe-id', str(self.id))
|
||||
@@ -1628,9 +1631,12 @@ actual arch.
|
||||
node_path = e.get('data-oe-xpath')
|
||||
if node_path is None:
|
||||
node_path = "%s/%s[%d]" % (parent_xpath, e.tag, index_map[e.tag])
|
||||
if branding and not (e.get('data-oe-model') or e.get('t-field')):
|
||||
e.attrib.update(branding)
|
||||
e.set('data-oe-xpath', node_path)
|
||||
if branding:
|
||||
if e.get('t-field'):
|
||||
e.set('data-oe-xpath', node_path)
|
||||
elif not e.get('data-oe-model'):
|
||||
e.attrib.update(branding)
|
||||
e.set('data-oe-xpath', node_path)
|
||||
if not e.get('data-oe-model'):
|
||||
return
|
||||
|
||||
|
||||
@@ -808,6 +808,55 @@ class TestTemplating(ViewCase):
|
||||
initial.get('data-oe-xpath'),
|
||||
"The node's xpath position should be correct")
|
||||
|
||||
def test_branding_inherit_top_t_field(self):
|
||||
view1 = self.View.create({
|
||||
'name': "Base view",
|
||||
'type': 'qweb',
|
||||
'arch': """
|
||||
<hello>
|
||||
<world></world>
|
||||
<world t-field="a"/>
|
||||
<world></world>
|
||||
<world></world>
|
||||
</hello>
|
||||
"""
|
||||
})
|
||||
self.View.create({
|
||||
'name': "Extension",
|
||||
'type': 'qweb',
|
||||
'inherit_id': view1.id,
|
||||
'arch': """
|
||||
<xpath expr="/hello/world[3]" position="after">
|
||||
<world t-field="b"/>
|
||||
</xpath>
|
||||
"""
|
||||
})
|
||||
arch_string = view1.with_context(inherit_branding=True).read_combined(['arch'])['arch']
|
||||
arch = etree.fromstring(arch_string)
|
||||
self.View.distribute_branding(arch)
|
||||
|
||||
# First t-field should have an indication of xpath
|
||||
[node] = arch.xpath('//*[@t-field="a"]')
|
||||
self.assertEqual(
|
||||
node.get('data-oe-xpath'),
|
||||
'/hello[1]/world[2]',
|
||||
'First t-field has indication of xpath')
|
||||
|
||||
# Second t-field, from inheritance, should also have an indication of xpath
|
||||
[node] = arch.xpath('//*[@t-field="b"]')
|
||||
self.assertEqual(
|
||||
node.get('data-oe-xpath'),
|
||||
'/xpath/world',
|
||||
'Inherited t-field has indication of xpath')
|
||||
|
||||
# The most important assert
|
||||
# The last world xpath should not have been impacted by the t-field from inheritance
|
||||
[node] = arch.xpath('//world[last()]')
|
||||
self.assertEqual(
|
||||
node.get('data-oe-xpath'),
|
||||
'/hello[1]/world[4]',
|
||||
"The node's xpath position should be correct")
|
||||
|
||||
def test_branding_primary_inherit(self):
|
||||
view1 = self.View.create({
|
||||
'name': "Base view",
|
||||
|
||||
Reference in New Issue
Block a user