-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problems with the <table> abstraction in the model #6506
Comments
I always wanted to make the conversion base on as simple mechanism as possible. The complexity should be kept under the hood and should not leak to converters. For non 1:1 mappings, the only reasonable solution I can see is doing a "reconversion" whenever we cannot handle a model change with an easy 1:1 converter. For instance, in case of tables, a table style can be converted with attrribute-to-attribute mapping. However, table heading rows count cannot. It should re-trigger conversion of the entire table. Unfortunately, the conversion system went the other way around and we have a lot of abstraction leaking to converters making them incomprehensible. IMO, this must change because there's simply no other way around. The issue that you fixed with change+enqueueChange is fixed in the command. But what about collaboration or undo? What about integration code and other features? There's a great chance that one of these change sources will try to modify the table too much at once. |
My thoughts on this matter:
Since we are talking about a bigger refactor, maybe we could think about totally different representation of a table? I've always thought that there must be a better way to do it. I've seen some discussions on Twitter in this area, too. I feel there's general agreement that there's something wrong with how tables are represented in HTML. Maybe instead of going more into HTML, let's get really outside of it? I wonder how spreadsheet applications represent their tables. I wanted to write that: But, in general, I think that we should simply delete most of the code we have and re-think how conversion works, how commands work, how post-fixers work. Start again with a better understanding of the feature and of how it fits our architecture. After all, I don't think that current model is really bad. But after another thought I change my mind: Of course, I don't have a full understanding of issues in tables. If you think that having 1:1 representation will solve some problems, then that's fine, let's go this way. We will move complexity into commands and post-fixers. If I wanted to propose removing a lot of code, we can remove the idea for the model as well. |
I'm afraid we need to discuss this f2f :D |
Dunno why we went in this direction (I wasn't here ;P). It looks like a single undo step requirement - but this can be "fixed". I was thinking about the same - especially that we already have a pattern for passing a batch to commands. The only other thing is that it might be desired to have a command that works on multi-cell selection.
This is a problem with moving stuff around (
I think that the problem here is that HTML |
I've updated the issue description with similar analysis from #6630. The conversation above was related to the "original issue description" (also in the first post). |
Another problems listed there #6630 (comment) (dunno I keep posting there). |
OK I had this thought that is either brilliant or completely dumb, but why we made editing so complex? The desired data must have What if we'd ditch Besides:
I don't see any real need for <figure>
<div>...</div> <!-- UI -->
<table>
<tr class="heading-row">
<th><p>Heding row cell</p></th>
<th><p>Heding row cell</p></th>
</tr>
<tr>
<th><p>Heading column cell</p></th>
<td><p>Data cell</p>
</tr>
</table>
</figure> Pros:
Cons:
|
I'd say this is a good last resort solution :D If we won't be able to handle this better on our side, then we can change the structure. However, it comes with its problems – the styles written for the content outside and inside the editor will need to differ. And there may be some a11y issues due to not using a full table structure. In general, as long as we're able to keep the structures similar we should do that. |
There has been no activity on this issue for the past year. We've marked it as stale and will close it in 30 days. We understand it may still be relevant, so if you're interested in the solution, leave a comment or reaction under this issue. |
We've closed your issue due to inactivity over the last year. We understand that the issue may still be relevant. If so, feel free to open a new one (and link this issue to it). |
Issue description (from #6630)
Atomic converters works in on operation at a time basis. In order to work out some of the above constrains they calculate operations based on the model state. This fails if more than two operations happens on a table.
Consider changing header rows from
2
to1
. The downcast converter:H2
(because it is at index which is after a heading section) finds its view element and move it to<tbody>
section.th
.Now consider removing multiple rows (
H2
andB1
). TheRemoveRow
command will:H2
row.1
.B2
.Now this will fail because heading rows converter sees the same attribute change and will assume that table is valid. But what this converter will do is:
B2
) and move it's view to<tbody>
.After table's attributes change conversion the remove row converter will step in. Removing elements from model is done on positions (offset in parent). So it will:
table
).2
).B2
to be removed instead ofH2
.B2
was removed instead ofH2
.So the spotted problems are:
enqueueChange()
- I don't see other option for the problem described here. The thing withenqueueChange()
is that run conversion on each step so it acts like step-by-step conversion but it looks like more work is done than necessary.headingRows
conversion. One idea is to have<tableRow isHeading="true">
- this will require some other checks (noisHeading
gaps have to be checked) than now but conversion "should" be simple for this case. And I don't see how we can make similar change with columns.Original issue description
It is rather a general list of spotted problems with current table abstraction which might be unsolvable or would require much work.
<tbody>
,<thead>
)WIP - the list should be updated with other issues.
Ad. 1 - No table sections in the model
After introducing table selection operations on table started to be more complex than anticipated when creating table conversion. The problem is that we do not have
header
orbody
in the model to make model simpler while HTML<table>
has them and those sections have some constrains. One of them is that a table cell cannot be spanned with cells from body section. This leads to various calculation when changing "simple" attribute of a table:headingRows
. This worked surprisingly well with simpler operations (ie remove 1 row, change headings count) or was a bug al along which didn't surfaced.The problem with remove row command (#6391) is that it removes multiple rows and changes
headingRows
in one action. TheheadingRows
attribute downcast works on moving rows around and it worked with one row being removed. It fails beautifully when more than one row is removed. This is because by default thetable
attributes are converted before removing rows. Thus this operates on different set of data than and should be re-written completely to anticipate this.The easy fix for this was to make
headingRows
being downcasted after table rows removal withmodel.enqueueChange
. The other way of dealing with this could be always re-creatingbody
andhead
sections and moving rows to them but it will probably fail in most scenarios with removing rows and changing heading rows count (ie algorithm could move to head rows being removed and thus creating invalid view state).The above leads to a my conclusion that not having 1:1 view to model projection requires from us handling some stuff carefully. IE
headingRows
operations in the model must be done always after modifying table structure because conversion must operate on target table state (number of rows) and we do not have coversion API to delay some operations rather then usingmodel.enqueueChange()
. This is a bit unfortunate as it tangles model and the view in an implicit (not obvious) way.If you'd like to see this fixed sooner, add a 👍 reaction to this post.
The text was updated successfully, but these errors were encountered: