-
-
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
A triggerBy
option that issues element re-render
#7956
Comments
To have this properly handled from top to bottom I'll start with:
|
I think that I have a solid base of test for the feature - as for now I don't think that any corner cases should be handled. And while writing it down I see that I lack tests for not re-converting element for changes below slot, ie do not re-convert for changes in a The other thing is that current API lacks some sort of the element binding (the case for outer/inner view elements maps to one model element - like all elements wrapped in |
I tried to make this work with table conversion. The base scenario works well and the code could be simplified a bit and more fluent in other parts. However, re-rendering on multiple changes (mixed with The current table refreshing logic is triggered for any conversion.for( 'editingDowncast' ).elementToElement( {
model: 'table',
view: downcastInsertTable( { asWidget: true } ),
triggerBy: [
'attribute:headingRows:table' // <-- this should handle (1)
]
} ); And ckeditor5/packages/ckeditor5-table/src/converters/table-heading-rows-refresh-post-fixer.js Line 25 in 1cab865
This works nice in tests but also showed me that I didn't add more complex test cases. The problem in table scenarios is when:
Why? I didn't know differ internals - there's a huuuuge if-else tree (I'd refactor this to be purely funcitonal maybe some day) that handles overlapping changes. For instance, if there's an
|
For starters, I'll try to write tests for similar cases in the engine and see if those shed some light on the issue or solutions. We might invalidate this case for now and revert table changes. The other thing is to implement Alternatively, (to not make the solution too complex to use from outside) information about "slot" should be available somewhere (it is in the mapper for instance) so I'll check that first. The goal is to not bloat the API from the inside and to figure things out internally. |
Oh, I have a similar failing test for this already. |
I was trying to handle complex cases of refresh events (9fa12db), a scenario that was kind of hard to figure out was:
with configuration like: conversion.for( 'downcast' ).elementToElement( {
model: 'complex',
view: () => { ... },
triggerBy: [
'attribute:foo:complex',
'insert:slot',
'remove:slot'
]
} ); What should happen is that Handling this on a However, the downcast dispatcher has this information as it handles My next steps will be to skip conversion of matched events either by:
As for now the 1) seems a bit to much attached to differ while 2) looks like a proper place to handle above. |
e3b8c4e: I've manage to dig out some issue that still need to be resolved, most likely covering the above post.
|
db8c17a: The full reconversion with slots is kinda working. The case to handle is a hybrid approach in which main element is handled by reconversion while adding/removing slots is done separately. If time allow I'll investigate this, however I'm worried that it would require API for a layered view items mapping ( |
So for so good. I've "fixed" the API for now, added some docs and removed debug code. Still to handle:
|
After some battling with table tests, it turned out that I've implemented the POC on the downcast helpers level. Which is not ideal. Table tests showed that removing old view and view momoization should be handled on the dispatcher level. The current form creates duplicated views when refreshing paragraphs in table cell. |
Most of the issues with table conversion were related to the refreshing table cell. I've refactored that part to refresh
Moving the logic from downcast helpers to the dispatcher was easier than I anticipated. |
The #1589 is a blocker for a group of tests in the engine. So without it, you could only write a whole-refresh item converter that would include creating slots. Tables have custom row insertion logic that does not rely on position mapping. |
ATM the engine tests are OK with one exception for failing table tests. In tables I have 3 failing tests and 5 ignored. Failing tests requires some investigation of the downcast conversion ,- minor issue. However ignored tests are worse as those cause browser to freeze as differ produces infinite loop condition in All of those changes might be tied together. I'd suspect some glitch in table conversion (maybe refresh() is used too often) or the differ still needs and improvement in order to properly handle this edge case. I'll try to investigate what set of changes produces the infinite loop. |
Re-converting whole thing + slot conversionThe table feature showed me the thoughtshortcomings of what I though was needed. Cases:
Always replaced by a new view structure. Relatively simple. <apple type="macintosh"></apple>
// converted to:
<div class="apple"><span class="apple-type">macintosh</span></div> Current use case: none.
<tree hasBugs="true"> // Element start, children are here
<paragraph>A</paragraph>
<paragraph alignment="right">B</paragraph>
</tree> // Element end
// converted to:
<div class="tree tree_with-bugs"> // Element start, content goes here
<p>A</p>
<p style="text-align: right">A</p>
</div> // Element start Current use case:
<tower levels="2" type="pretty"> // Element start, children are here
<paragraph>A</paragraph>
<paragraph alignment="right">B</paragraph>
</tower> // Element end
// converted to:
<div class="tower tower-pretty"> // Element start
<div class="tower-level-1">
<div class="tower-level-2"> // Content goes here
<p>A</p>
<p style="text-align: right">A</p>
</div>
</div>
</div> // Element start Current use case: The
Here slots not wrapped in a particular wrapper element or other elements might be rendered alongside them. <train type="steam"> // Element start, slots are here
<car>
<paragraph>A</paragraph>
</car>
<car>
<paragraph alignment="right">B</paragraph>
</car>
</train> table cell // Element end
// converted to:
<div class="train train-steam"> // Element start
<div class="tender"><span class="coal"></span></div>
<div class="car">
<p>A</p>
</div>
<div class="car">
<p style="text-align: right">A</p>
</div>
</div> // Element end Demo with The problem here is that each slot must be fully controlled by the main converter. You can not add an The tables turned to be a tricky - slots at the
|
Case 1: The less problematic case IMO - self contained element without children - tested, works. Case 2: I implemented in #8099 as Case 3: Requires #1589 - an API to tell the mapper where elments start/ends in the view tree. Partially handled by double-bindings in some places but it is buggy. Case 4: I'd postpone this case for own ticket. Havin #1589 should easy implementing this. Additionally attributes conversion for rendered |
To conclude this ticekt with a minimal use case I'd go with enabling the most obvious solutions for reconversion - mostly as a demo/feature guides. Other things should be fixed by the follow-ups to unblock refreshing a table with minimal view changes and allowing to implement |
So the remaining thing is to fix memoization used together with It turned out that I've implemented view memoization only when the "slots" are defined and missed the simplest case where a block element is refreshed and its children should be retained. The Changes to the ATM I'm going to fix the memoization logic to make those tests green ( 7e359d8 ). |
So the memoization works correctly in the downcast dispatcher and the logic should be simpler as the last thing to be removed was slot binding from the mapper. The code changes are now restricted to |
Feature (engine): Introduce automatic model-to-view reconversion by defining `triggerBy` option for `elementToElement()` conversion helper. Closes #7956. Other (table): Table cell contents refreshing for the editing view will now make fewer view updates.
triggerBy
option that issues element re-rendertriggerBy
option that issues element re-render
Provide a description of the task
Implement the base API for the slot conversion API. This should provide a minimal, top-level API for changes defined there and researched in: #7729.
Goals:
The text was updated successfully, but these errors were encountered: