1

Topic: isBlock on custom elements

I'm getting some strange behavior, I can't seem to get a custom element to register at block level.

I have init as:

{extended_valid_elements : 'list-item', custom_elements : 'list-item'}

Then I have some code:

var t = this, ed = t.ed, dom = ed.dom;
console.log(ed.selection.getNode().nodeName);
console.log(dom.isBlock(ed.selection.getNode()));

For a given selection the log shows:

LIST-ITEM
false

After inspecting the tinyMCE code, this theoretically looks like it should work, custom elements should get added to the Array which isBlock checks. Am I just missing something here?

Last edited by ejdanderson (2012-07-31 00:46:44)

2

Re: isBlock on custom elements

Well, I looked into the code. All I see in isBlock is:

...
if (type)
                return !!(type === 1 && blockElementsMap[node.nodeName]);
...

And looks like blockElementsMap is only set at one single place:

blockElementsMap = 'h1,h2,h3,h4,h5,h6,hr,p,div,address,pre,form,table,tbody,thead,tfoot,' + 
                        'th,tr,td,li,ol,ul,caption,blockquote,center,dl,dt,dd,dir,fieldset,' + 
                        'noscript,menu,isindex,samp,header,footer,article,section,hgroup';
    blockElementsMap = makeMap(blockElementsMap, ',', makeMap(blockElementsMap.toUpperCase()));

So custom element probably didn't make into the block elements map.

3

Re: isBlock on custom elements

This is where I thought they got loaded into the blockElementsMap:

    // Adds custom non HTML elements to the schema
        function addCustomElements(custom_elements) {
            var customElementRegExp = /^(~)?(.+)$/;

            if (custom_elements) {
                each(split(custom_elements), function(rule) {
                    var matches = customElementRegExp.exec(rule),
                        inline = matches[1] === '~',
                        cloneName = inline ? 'span' : 'div',
                        name = matches[2];

                    children[name] = children[cloneName];
                    customElementsMap[name] = cloneName;

                    // If it's not marked as inline then add it to valid block elements
                    if (!inline)
                        blockElementsMap[name] = {};

                    // Add custom elements at span/div positions
                    each(children, function(element, child) {
                        if (element[cloneName])
                            element[name] = element[cloneName];
                    });
                });
            }
        };

and then later on in the init process:

addCustomElements(settings.custom_elements);

I wonder if its not match due to case on the key? I'll give that a whirl.

Last edited by ejdanderson (2011-08-12 23:37:16)

4

Re: isBlock on custom elements

Yup looks like that was the case. Opened a ticket.

Last edited by ejdanderson (2011-08-12 23:57:39)

5

Re: isBlock on custom elements

Oh interesting...
If only I was looking at the latest source code...
It looks like that was recently introduced in 3.4.3.1.

ejdanderson wrote:

Yup looks like that was the case. Opened a ticket.

Nice find :-)

6

Re: isBlock on custom elements

As Jacky mentioned, this support isn't there yet for older versions of tinyMCE. You can get around this by setting the array on init of a plugin:

tinymce.html.Schema.blockElementsMap['NODE-NAME'] = {};

7

Re: isBlock on custom elements

ejdanderson wrote:

As Jacky mentioned, this support isn't there yet for older versions of tinyMCE. You can get around this by setting the array on init of a plugin:

tinymce.html.Schema.blockElementsMap['NODE-NAME'] = {};

For what its worth, this solution no longer works in 5.x, though the isBlock still is case sensitive adding the capitalized version of the tags to custom the custom elements now works.

{extended_valid_elements : 'LIST-ITEM', custom_elements : 'LIST-ITEM'}