-
-
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
Error during conversion of text inside element when specific attribute converters are defined for both elements #4440
Comments
If you disable the first converter: editor.conversion.for( 'downcast' ).add( downcastAttributeToElement( {
model: {
key: 'test',
name: '$text'
},
view: ( value, writer ) => {
return writer.createAttributeElement( 'span', { test: value } );
}
} ) ); the error still occur. And it even make a sense because in the second converter: editor.conversion.for( 'downcast' ).add( downcastAttributeToAttribute( {
model: 'test',
view: 'test'
} ) ); we want to convert every When I changed a little the test scenario: editor.model.change( writer => {
const root = editor.model.document.getRoot();
const p = root.getChild( 0 );
const text = writer.createText( 'FooBar', /*{ 'test': 3 }*/ );
writer.setAttribute( 'test', 3, p );
writer.insert( text, p );
} ); In the view I got: |
☝️ It looks like the "generic" converter treats all nodes as elements and when encounters a text nodes it fails. IMHO when text node is encountered, the generic converter should act the same way as "text specific" one - wrapping text in a span with an attribute applied. The second idea we have discussed with @pomek was to apply the attribute to text parent element but it may become tricky for more complex scenarios (e.g. same attribute with different values for text and its parent). |
Your converters are fine. It should work correctly, as you intended, so there is a bug somewhere. You shouldn't do anything like this:
First, I think that the "generic" (or let's say |
Recently I talked with @scofalik about the bug. I checked which converters are executed during for the test scenario. I put a For such scenario: conversion.for( 'downcast' ).add( downcastAttributeToElement( {
model: {
key: 'test',
name: '$text'
},
view: ( value, writer ) => {
return writer.createAttributeElement( 'span', { test: value } );
},
} ) );
conversion.for( 'downcast' ).add( downcastAttributeToAttribute( {
model: 'test',
view: 'test'
} ) );
model.change( writer => {
const foo = writer.createText( 'FooBar', { test: 3 } );
writer.insert( foo, modelRoot );
} ); Calls look: After removing the So it seems that the |
I have checked it with a minimal example like: editor.conversion.for( 'downcast' ).add( downcastAttributeToAttribute( {
model: 'test',
view: 'test'
} ) );
editor.model.change( writer => {
const root = editor.model.document.getRoot();
const p = root.getChild( 1 );
const text = writer.createText( 'FooBar', { 'test': 3 } );
writer.insert( text, p );
} ); and indeed the above is enough to reproduce the issue. So second converted mentioned in the initial report does not affect it at all.
☝️ This seems to be cause of this issue, that When When I assume: editor.conversion.for( 'downcast' ).add( downcastAttributeToAttribute( {
model: 'test',
view: 'test'
} ) ); converter should not be executed for nodes which cannot directly have attributes. But I don't see any check for this in the code 🤔
Btw. I have checked the above and it seems conversion is called for the selection only if |
One more thing to clarify, the direct cause of the error is the fact that so |
Fix: Do not run attribute-to-attribute downcast conversion on text node attributes. Closes #1587.
Follow up of #1317.
Considering conversions defined like:
and setting model data like:
throws an
Cannot read property '_setAttribute' of undefined
error:Works fine if text is inserted into
root
, but when inserted as a child ofp
the error is thrown. The interesting thing is when generic conversion is removed from the example above:everything starts to work fine.
The text was updated successfully, but these errors were encountered: