U4-1736 - Support "element + class" styles in TinyMCE

Created by Stephan 19 Feb 2013, 11:33:48 Updated by Barry Fogarty 09 Aug 2016, 12:21:08

Relates to: U4-6267

Relates to: U4-7475

At the moment, styles in TinyMCE can be either an element (h2) which will change the current block to that element, or a class (.foo) which will change the style of the selection. But a combination of both is not supported eg h2.foo will ''not'' change the current block to h2 ''and'' add the class, as we would expect.

Comments

Antony Briggs 24 Apr 2014, 08:54:22

I've been working on a patch for this for Umbraco 7.

TinyMCE supports this functionality out of the box (at least V4 that Umbraco 7 uses does) its only a matter of translating the css selector into appropriate configuration for TinyMCE.

The TinyMCE documentation is here: http://www.tinymce.com/wiki.php/Configuration:style_formats http://www.tinymce.com/wiki.php/Configuration:formats

I suspect the reason this hasn't been done before is that it's not obvious what you want the style to do from it's css selector alone:

  1. Should the format be applied inline, create a block element or only apply to certain existing block level elements?

for example: div.class - Should this format a) transform the selected element into a div and apply the class or b) should it the format only apply when the user has selected a div. img.class - If the answer above was a) then what happens in the case of an img tag? you can't turn a p into an img.

  1. If it's a block level element, should it wrap the selected elements or replace them.

for example: div.class - Should the format a) turn the selected paragraph into a div or b) wrap the selected paragraph(s) with a div? what about other block level elements like blockquotes or the plethora of HTML5 ones?

The Umbraco 7 implementation did the following:

  1. if the selector started with a "#", create an inline span and add an id= attribute (e.g. "#identifier")
  2. if the selector started with a ".", create an inline span and add an class= attribute (e.g. ".
  3. otherwise transform the selection into the specified block level element (e.g. "h2")

In the project I'm working on, I've isolated the following use cases:

  1. add inline classes (e.g. "span.class")
  2. change to a particular block level element optionally with a class specified (e.g. h2.class )
  3. wrapping in a block level element (e.g. div.class will wrap the selected elements in a div and apply the class)
  4. apply a class to an existing block level element (e.g. img.class or tr.class)

I've had some difficulty in coming up with an explicit selector syntax to identify the use cases so would welcome some feedback on the following suggested syntax for the use cases above:

  1. ".class" (same as umbraco currently does)
  2. "h2" or "h2.class"
  3. "!div" or "!blockquote" (optionally with a class name - This was inspired by the upcoming CSS4 spec for selecting the target to apply the styles to)
  4. "* img.class" or "* tr.class" (This was inspired by the fact that TinyMCE will apply the class to any elements of the appropriate type within the selection e.g. if you select a p containing an image, it will apply the class to the image only)

It may be possible to infer the last two use cases by the type of block element involved?

If no one has any objections to the above syntax, I'll prepare a pull request early next week.

TTFN

Ant

(Sorry for the long read!)


Anders Brohäll 24 Apr 2014, 11:22:43

Sounds like you've been struggeling. Do prepare the pull request! :)


Zac 14 May 2014, 18:05:22

Antony - any update on the pull request? We are looking at implementing the same thing.


Bjørn Fridal 29 May 2014, 11:02:57

Hi, any news on the patch? I think it would be very handy for a lot of people, me included.


Brian Patton 30 Jun 2014, 15:47:00

Any updates on this functionality? v6 was applying classes to my without issue, but now after upgrading to v7, it is wrapping the images w/ span (which is not useful for block level type adjustments > i.e. floating, margins, etc.)


Rick Mason 08 Jul 2014, 12:18:16

Use case 4 should be for any element, not just block level. I'm looking to apply a class to a link and it doesn't look possible with the way Umbraco configures TinyMCE.

I don't think the * is needed in the selector, as [tagname].[classname] is an identifiable pattern which could be used.


Steffen Dam 30 Jul 2014, 12:19:35

Having this issue too, making some things quite hard to style. Is there any update/news to this?


Geoff Beaumont 11 Nov 2014, 12:49:35

Hi Anthony,

Any progress on this?

U7's rich text editor is really pretty broken as it stands (previous versions might have been a bit unreliable in what they applied styles to, but at least it was possible to style block level elements - in U7 it can only be done by editing source, which is completely useless for most editors).

Other platforms that use tinymce manage to do this much better, so it is at least in part about Umbraco.


Shannon Deminick 12 Feb 2015, 23:01:23

PR is here: https://github.com/umbraco/Umbraco-CMS/pull/630


Shannon Deminick 12 Feb 2015, 23:23:53

I have merged in this PR and am testing a few things. The PR makes sense however it doesn't cover all use cases outlined by Anthony but allows you to define element + classes (including composite ones), so you could do 'div.class1.class2' which will become <div class='class1 class2', etc...

For more advanced rule sets, let's open a new issue for that.


Shannon Deminick 12 Feb 2015, 23:32:17

I've created a new issue here to look at more advanced rules: http://issues.umbraco.org/issue/U4-6267


Matt Muller 21 Feb 2015, 09:55:37

Looks like this needs to be added to the grid rte as well - I believe that code lives in a different spot?


Christopher Bell 02 Mar 2015, 20:16:46

How do we implement this now in 7.2.2? Our custom configuration from 7.1.8 no longer works. O_o http://issues.umbraco.org/issue/U4-6344

Any feedback would be wonderful!


Lars Baunwall 30 Nov 2015, 19:29:53

@Shandem I can't get this to work in 7.3.2 - if I try to add e.g. an h1.myClass (alias) to my RTE stylesheet, it is ignored by the RTE in Grid editor mode.

This is only the case in the Grid RTE, it works as expected in an ordinary RTE, where h1.myClass becomes <h1 class="myClass"....


Barry Fogarty 09 Aug 2016, 12:19:21

I can confirm @larsbuur's report above - specific element styling e.g. h1.myClass works fine in a non-grid RTE but the styles are just ignored when the RTE is ignored in the grid. NB It does work OK if you use a global style_formats config in TinyMCE (see http://issues.umbraco.org/issue/U4-6344). This is not ideal however, as we cannot have separate configurations for different RTE instances. Using v7.4.3. Is there an open issue this can be linked to, that pertains specifically to the Grid RTE?


Barry Fogarty 09 Aug 2016, 12:21:08

Ah yes - link to http://issues.umbraco.org/issue/U4-7475 - seems a fix is due in 7.5


Priority: Normal

Type: Feature (request)

State: Fixed

Assignee: Shannon Deminick

Difficulty: Normal

Category:

Backwards Compatible: True

Fix Submitted: Pull request

Affected versions: 7.4.2

Due in version: 7.2.2

Sprint:

Story Points:

Cycle: