I'm using the latest/current TinyMCE editor (<script type="text/javascript" src='https://cdn.tinymce.com/4/tinymce.min.js'></script>) and it doesn't seem capable of displaying <svg>. I have some HTML saved in a database which contains some <svg>. When loaded in TinyMCE, it doesn't display.
Is this a known issue (I've searched and haven't found much)? Any workarounds?
TinyMCE strips empty and invalid tags. You can solve it by
Adding ' ' to each empty element:
svg.find('*').each(function() {
if (!$(this).html()) {
$(this).text(' ');
}
});
here svg is your jQuery wrapped svg element.
Extending the valid elements according to the svg element reference*
extended_valid_elements: "svg[*],defs[*],pattern[*],desc[*],metadata[*],g[*],mask[*],path[*],line[*],marker[*],rect[*],circle[*],ellipse[*],polygon[*],polyline[*],linearGradient[*],radialGradient[*],stop[*],image[*],view[*],text[*],textPath[*],title[*],tspan[*],glyph[*],symbol[*],switch[*],use[*]"
*Note I added only the elements relevant for my case.
I tried Koen's first suggestion and it worked for existing SVG content (I added this in the setup callback). However it still filtered the SVG tags out when pasting HTML into the source code editor and then confirming the dialog.
After digging a bit into TinyMCE's source code to see where those elements are actually removed (it's in the DomParser class) I found an undocumented editor setting for the Schema class that specifies tags that are allowed to be empty without being removed. The only annoying thing is that you can't use it to add to the existing list, you can only override it. So when setting it you have to list the tags it has in there by default as well. Use this in the settings that you provide to TinyMCE when initialising it:
// First the list of tags that it normally knows about by default:
non_empty_elements: "td,th,iframe,video,audio,object,script,pre,code,area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,source,wbr,track"
// Now we add tags related to SVGs that it doesn't normally know about:
+ "svg,defs,pattern,desc,metadata,g,mask,path,line,marker,rect,circle,ellipse,polygon,polyline,linearGradient,radialGradient,stop,image,view,text,textPath,title,tspan,glyph,symbol,switch,use",
This way these SVG tags should never be filtered out because they are empty - as long as they are also valid in general, e.g. by setting the extended_valid_elements as Koen suggested above or by allowing all elements (not recommended as it leaves you vulnerable to XSS attacks):
extended_valid_elements: "*[*]"
Please note that this worked for my version 4.5.8 of TinyMCE. Since this setting is undocumented it might not work anymore in current or future versions. Also they might've adjusted the default list that I'm overriding here in later versions. Find nonEmptyElementsMap and shortEndedElementsMap in Schema.js in their source code to find the default list in your version (the two lists get combined) and note that in there the tags are separated by spaces but when you supply a list yourself the list is separated by commas (for whatever reason).
Seams to be TinyMCE that removes it because it is an empty tag: http://world.episerver.com/forum/developer-forum/-EPiServer-75-CMS/Thread-Container/2015/1/tinymce-and-svgs/
You might be able to use this inside the init:
extended_valid_elements : "svg[*]",
It works with other empty tags etc, but have never tried with SVG.
From the forum post I linked to:
ok,I did some debugging into TinyMCE and the problem seems to be that
the svg element is detected as being empty and therefor removed.
Unfortunatley there is no config way to change this behavior but there
are some workarounds.
Always have a name attibute for the svg element: <svg name="something"
Always have a data-mce attribute for the svg element: <svg data-mce-something="something"
Include some text content within the svg element: <svg> </svg> Using these techniques i could succesfully store
inline svg in an xhtml property
I made it work by adding all valid SVG elements to the extended_valid_elements property of the settings object while initializing TinyMCE, no other action was needed
For your convenience here's the full list of SVG elements I used
a[*],altGlyph[*],altGlyphDef[*],altGlyphItem[*],animate[*],animateMotion[*],animateTransform[*],circle[*],clipPath[*],color-profile[*],cursor[*],defs[*],desc[*],ellipse[*],feBlend[*],feColorMatrix[*],feComponentTransfer[*],feComposite[*],feConvolveMatrix[*],feDiffuseLighting[*],feDisplacementMap[*],feDistantLight[*],feFlood[*],feFuncA[*],feFuncB[*],feFuncG[*],feFuncR[*],feGaussianBlur[*],feImage[*],feMerge[*],feMergeNode[*],feMorphology[*],feOffset[*],fePointLight[*],feSpecularLighting[*],feSpotLight[*],feTile[*],feTurbulence[*],filter[*],font[*],font-face[*],font-face-format[*],font-face-name[*],font-face-src[*],font-face-uri[*],foreignObject[*],g[*],glyph[*],glyphRef[*],hkern[*],image[*],line[*],linearGradient[*],marker[*],mask[*],metadata[*],missing-glyph[*],mpath[*],path[*],pattern[*],polygon[*],polyline[*],radialGradient[*],rect[*],script[*],set[*],stop[*],style[*],svg[*],switch[*],symbol[*],text[*],textPath[*],title[*],tref[*],tspan[*],use[*],view[*],vkern[*],a[*],animate[*],animateMotion[*],animateTransform[*],circle[*],clipPath[*],defs[*],desc[*],discard[*],ellipse[*],feBlend[*],feColorMatrix[*],feComponentTransfer[*],feComposite[*],feConvolveMatrix[*],feDiffuseLighting[*],feDisplacementMap[*],feDistantLight[*],feDropShadow[*],feFlood[*],feFuncA[*],feFuncB[*],feFuncG[*],feFuncR[*],feGaussianBlur[*],feImage[*],feMerge[*],feMergeNode[*],feMorphology[*],feOffset[*],fePointLight[*],feSpecularLighting[*],feSpotLight[*],feTile[*],feTurbulence[*],filter[*],foreignObject[*],g[*],hatch[*],hatchpath[*],image[*],line[*],linearGradient[*],marker[*],mask[*],metadata[*],mpath[*],path[*],pattern[*],polygon[*],polyline[*],radialGradient[*],rect[*],script[*],set[*],stop[*],style[*],svg[*],switch[*],symbol[*],text[*],textPath[*],title[*],tspan[*],use[*],view[*],g[*],animate[*],animateColor[*],animateMotion[*],animateTransform[*],discard[*],mpath[*],set[*],circle[*],ellipse[*],line[*],polygon[*],polyline[*],rect[*],a[*],defs[*],g[*],marker[*],mask[*],missing-glyph[*],pattern[*],svg[*],switch[*],symbol[*],desc[*],metadata[*],title[*],feBlend[*],feColorMatrix[*],feComponentTransfer[*],feComposite[*],feConvolveMatrix[*],feDiffuseLighting[*],feDisplacementMap[*],feDropShadow[*],feFlood[*],feFuncA[*],feFuncB[*],feFuncG[*],feFuncR[*],feGaussianBlur[*],feImage[*],feMerge[*],feMergeNode[*],feMorphology[*],feOffset[*],feSpecularLighting[*],feTile[*],feTurbulence[*],font[*],font-face[*],font-face-format[*],font-face-name[*],font-face-src[*],font-face-uri[*],hkern[*],vkern[*],linearGradient[*],radialGradient[*],stop[*],circle[*],ellipse[*],image[*],line[*],path[*],polygon[*],polyline[*],rect[*],text[*],use[*],use[*],feDistantLight[*],fePointLight[*],feSpotLight[*],clipPath[*],defs[*],hatch[*],linearGradient[*],marker[*],mask[*],metadata[*],pattern[*],radialGradient[*],script[*],style[*],symbol[*],title[*],hatch[*],linearGradient[*],pattern[*],radialGradient[*],solidcolor[*],a[*],circle[*],ellipse[*],foreignObject[*],g[*],image[*],line[*],path[*],polygon[*],polyline[*],rect[*],svg[*],switch[*],symbol[*],text[*],textPath[*],tspan[*],use[*],g[*],circle[*],ellipse[*],line[*],path[*],polygon[*],polyline[*],rect[*],defs[*],g[*],svg[*],symbol[*],use[*],altGlyph[*],altGlyphDef[*],altGlyphItem[*],glyph[*],glyphRef[*],textPath[*],text[*],tref[*],tspan[*],altGlyph[*],textPath[*],tref[*],tspan[*],clipPath[*],cursor[*],filter[*],foreignObject[*],hatchpath[*],script[*],style[*],view[*],altGlyph[*],altGlyphDef[*],altGlyphItem[*],animateColor[*],cursor[*],font[*],font-face[*],font-face-format[*],font-face-name[*],font-face-src[*],font-face-uri[*],glyph[*],glyphRef[*],hkern[*],missing-glyph[*],tref[*],vkern[*]