Opened 5 years ago

Closed 5 years ago

#12854 closed Bug (invalid)

Changing widget elements inner tag's attributes does not seem to work

Reported by: Matti Järvinen Owned by:
Priority: Normal Milestone:
Component: UI : Widgets Version:
Keywords: Cc:

Description

Image src is changed after switching image from widget's own dialog. Data function is called with proper attributes (with changed image src) and new image is shown in the editor WYSIWYG. There is no downcast function since HTML structure doesn't change.

When I switch to source mode changes to contactImage src attribute are lost. It is as if changing widget element's inner tag attributes with setAttribute in widget data does not register as a change.

    editables: {												
        contentName: {
            selector: '.name'
        },
        contentJobTitle: {
            selector: '.jobTitle'
        }
    },
    ...
    template:
    '<div class="NID_contact" vocab="http://schema.org/" typeof="Person">'+
        '<div class="contact card row">'+
            '<div class="contact-photo col-xs-12 col-sm-3">'+
                '<img class="contactImage roundcorners" property="image" alt="" src="/img/default.png" />'+									
            '</div>'+
            '<div class="contact-details col-xs-12 col-sm-9">'+									
                '<div class="contactHeader">'+																			
                    '<h2 class="name" property="name">'+
                        'Firstname Surname'+
                    '</h2>'+
                    '<p class="jobTitle" property="jobTitle">'+
                        'Job Title'+
                    '</p>'+							
                '</div>'+
            '</div>'+
        '</div>'+
    '</div>',
    ...
    data: function() {
    
        // regex for trim
        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim
        var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
        
        
        var img = this.element.findOne('.contactImage');
        
        if(img != null)
        {
            img.setAttribute('src',this.data["img"].replace(rtrim,''));
        }        
    }                                     

To get my widget working I had to define terrible downcast function:

    downcast: function(element)
    {
        // regex for trim      
        var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
        
        element.children[0].children[0].children[0].attributes.src = this.data["img"].replace(rtrim,'');
        

        return element;
    
    },


Is there an easier way to select element's children preferably by class with CKEditor in downcast like ckeditor.dom.element.findOne for ckeditor.htmlparser.element ?

Change History (1)

comment:1 Changed 5 years ago by Piotrek Koszuliński

Resolution: invalid
Status: newclosed
Version: 4.4.4

There's a small detail that one needs to know when working with images, but no one would ever look for it in the docs, so it isn't documented.

To change image's src attribute you also need to change data-cke-saved-src. The reason for this argument to exist is that browsers (Blink/Webkit IIRC) change the src attribute to a full path. So the only way to preserve the exact value set by the user is to keep the value in a second attribute. When you get data from the editor, the data processor moves data-cke-saved-src attributes to src.

To get my widget working I had to define terrible downcast function:

It actually isn't that terrible because it does similar thing to what I explained above :). The only problem is that accessing an image is ugly, but there's no method for it currently. This situation is a bit tricky, because we cannot implement something like findOne() for htmlParser.element, because it would be huge. Perhaps some simplified method accepting condition (callback or an element name for instance) could be implemented. I reported #13267 for that. You can find a small workaround there.

Note: See TracTickets for help on using tickets.
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy