Page MenuHomePhabricator

DOM scopes / constraints inconsistently defined for transcluded lists and templates
Open, MediumPublic

Description

While investigating current templated sibling node use cases in the Parsoid DOM spec, I noticed that several template-affected structures aren't consistently marked as such in Parsoid output.

List not marked as template-affected despite templated list items

Input:

* foo
{{echo|* bar}}
* baz

Result: Only the 'bar' list item is marked as template-affected.
Expected result: The list is marked as template-affected. If the embedded template returned just 'bar', the entire list would break up, despite the list not being template-affected. The rendering as a list thus depends on the wikitext returned by the nested template, which isn't predictable in the general case. The list element is the closest DOM scope, so should be marked as template-affected, as it might be broken up into two lists depending on the return value of the template.

Table not marked as template-affected despite templated table cell / arbitrary element

Input:

{|
| foo
{{echo|
{{!}} bar}}
|}

Result: Only a single table cell is marked as template-affected.
Expected result: Since the table is the closest containment structure / DOM scope that can be reasonably expected to contain any sensible expansion of embedded templates, it should be marked as template-affected.

This is indeed what happens when the template returns slightly different wikitext, illustrating the inconsistency in behavior:

{|
| foo
{{echo|
{{!}}- 
{{!}} bar}}
|}

Both cases suggest a need for a more consistent definition of DOM constraints and -scopes, as discussed in the Parsoid/DOM_notes page on mediawiki.org and T114444: [RFC] Introduce notion of DOM scopes in wikitext.

Event Timeline

GWicke raised the priority of this task from to Needs Triage.
GWicke updated the task description. (Show Details)
GWicke added a subscriber: GWicke.
GWicke renamed this task from Templated list items don't mark list as templated to DOM scopes / constraints inconsistently defined for transcluded lists and templates.Nov 8 2015, 6:26 AM
GWicke added a project: Parsoid.
GWicke set Security to None.
GWicke removed a subscriber: Aklapper.
Arlolra triaged this task as Medium priority.Nov 18 2015, 4:11 AM
Arlolra added subscribers: ssastry, Arlolra.

We wrap the tightest region possible to enable the most amount of DOM editing.

Result: Only a single table cell is marked as template-affected.

That's not true (or at least it isn't on master now). Both tds are marked as template affected, which is arguably a bug in the current behaviour. Same goes for the second table example.

λ (master) cat t | node bin/parse --dump dom:pre-encap
------ DOM: pre-encapsulation -------
<body data-parsoid="{&quot;tagId&quot;:1,&quot;tmp&quot;:{},&quot;dsr&quot;:[0,41,0,0]}" data-mw="{}"><meta about="#mwt2" id="mwt2" typeof="mw:Transclusion" data-parsoid="{&quot;tsr&quot;:[0,2],&quot;tmp&quot;:{},&quot;dsr&quot;:[0,2,null,null]}"><table data-parsoid="{&quot;tsr&quot;:[0,2],&quot;tagId&quot;:2,&quot;tmp&quot;:{},&quot;dsr&quot;:[0,39,2,2]}" data-mw="{}">
<tbody data-parsoid="{&quot;tmp&quot;:{},&quot;dsr&quot;:[3,37,0,0]}" data-mw="{}"><tr data-parsoid="{&quot;tmp&quot;:{},&quot;autoInsertedEnd&quot;:true,&quot;autoInsertedStart&quot;:true,&quot;dsr&quot;:[3,null,0,0]}" data-mw="{}"><td data-parsoid="{&quot;tsr&quot;:[3,4],&quot;tmp&quot;:{&quot;noAttrs&quot;:true},&quot;tagId&quot;:3,&quot;autoInsertedEnd&quot;:true,&quot;dsr&quot;:[3,null,1,0]}" data-mw="{}"> foo
<meta typeof="mw:Transclusion" about="#mwt1" data-parsoid="{&quot;tsr&quot;:[9,36],&quot;src&quot;:&quot;{{echo|\n{{!}}- \n{{!}} bar}}&quot;,&quot;tmp&quot;:{&quot;tplarginfo&quot;:&quot;{\&quot;dict\&quot;:{\&quot;target\&quot;:{\&quot;wt\&quot;:\&quot;echo\&quot;,\&quot;href\&quot;:\&quot;./Template:Echo\&quot;},\&quot;params\&quot;:{\&quot;1\&quot;:{\&quot;wt\&quot;:\&quot;\\n{{!}}- \\n{{!}} bar\&quot;}}},\&quot;paramInfos\&quot;:[{\&quot;k\&quot;:\&quot;1\&quot;,\&quot;srcOffsets\&quot;:[16,16,16,34],\&quot;spc\&quot;:[\&quot;\&quot;,\&quot;\&quot;,\&quot;\&quot;,\&quot;\&quot;]}]}&quot;},&quot;tagId&quot;:4,&quot;dsr&quot;:[9,36,null,null]}" data-mw="{}"></td></tr>
<tr data-parsoid="{&quot;startTagSrc&quot;:&quot;|-&quot;,&quot;tagId&quot;:5,&quot;tmp&quot;:{},&quot;autoInsertedEnd&quot;:true,&quot;dsr&quot;:[null,36,null,0]}" data-mw="{}"> 
<td data-parsoid="{&quot;tmp&quot;:{&quot;noAttrs&quot;:true},&quot;tagId&quot;:6,&quot;autoInsertedEnd&quot;:true,&quot;dsr&quot;:[null,36,null,0]}" data-mw="{}"> bar<meta typeof="mw:Transclusion/End" about="#mwt1" data-parsoid="{&quot;tsr&quot;:[null,36],&quot;tagId&quot;:8,&quot;tmp&quot;:{},&quot;dsr&quot;:[null,36,null,null]}" data-mw="{}"></td></tr>
</tbody></table><meta about="#mwt2" typeof="mw:Transclusion/End" data-parsoid="{&quot;tmp&quot;:{},&quot;dsr&quot;:[39,39,null,null]}">

</body>
----------------------------

The meta is being closed into the td with Foo, and then when wrapTemplates.js find the common parent, it lands on the table, since both trs are included.

In the first table example, the tds are siblings, so it stops there.

So, the fix is probably to push the trailing meta outside of the auto-closed td.

/cc @ssastry

This is an old debate Gabriel and I have had about template encapsulation. :-)

But, I think DOM scopes can help resolve this debate without having to force an expansion of template-affected content, i.e. it is not a bad thing to reparse an entire DOM scope whenever either the template is edited or content is edited. So, yes, this will force a reparse of a larger context (list or table instead of a list item or a table cell/row), but it eliminates the need to mark the entire list / table as being template affected.

Of course, if the template itself has some balancing markers that dictate how its content should be handled as in T114445: [RFC] Balanced templates, it might provide a smaller incremental parsing context. But, that is a hand-wavy comment since we are still not yet at the stage where we have identified all the balancing types that we might introduce for template content.

But, in either case, either via dom scopes or via balancing-type markers, we can identify the right reparsing context without forcing the entire list/table to be marked as template-affected.

Ok, but what about the bug in our current strategy I've identified there.

Ok, but what about the bug in our current strategy I've identified there.

Not worth it ... unless it is actually a real problem in production pages.

LGoto moved this task from Feature requests to Future Ideas on the Parsoid board.