Wrapping SectionBlock in DIV in the HTML Renderers

Hi devs,

A user has approached me with the request of being able to use CSS to indent heading depending on their level (either just the heading content or the heading + content). Something similar to https://stackoverflow.com/questions/46690572/indent-content-based-on-headings

There are some complex ways to achieve this using the current HTML structure. For example: https://stackoverflow.com/a/46690811/153102

However, I think it could be a good idea to modify the HTML Renderers to do materialize the SectionBlock in the HTML for some use cases like this one. A first idea would be to use DIV with a class attribute (e.g. <div class="xwiki-section">).

In the initial discussion I had with other devs, the following points were brought up.

From @tmortagne:

We would need to modify the HTML parsers to handle this since otherwise the DIV would be converted to GroupBlock

From @mflorea:

I don’t think it’s a good idea to wrap sections in DIVs:

  • we end up with headings inside nested DIVs which breaks the current section editing: the section edit pencils are shown only for top level headings (direct children of #xwikicontent).
  • it will break any XWiki extension that expects the headings to be directly under the content wrapper. Numbered Paragraphs and Numbered Headings?
  • the nested DIVs will make WYSIWYG editing more difficult
    • first, in order to match the view mode, the WYSIWYG editor would have to generate the nested section DIVs also when you create a heading
    • once you are inside a section DIV (e.g. for H2) and you want to create a new heading of the same level or higher (e.g. for H1) you need to get out of the section DIV, or the editor needs to do this automatically…
    • editing content wrapped in DIVs is cumbersome and unexpected for the user

I’d like to discuss 2 points in this thread:

  1. How could we help the user achieve the heading indentation, if not using DIVs?
  2. Is it a good idea to use DIV to materialize SectionBlock so that some JS or CSS can be done more easily on sections by users of XWiki? Marius raised some good points but maybe the issues can be fixed. I think that if we were starting writing XWiki today and we were deciding how our HTML would look like, we would probably use a DIV to materialize the sections so that operations can be done on them more easily.

Let’s discuss!

Indeed, it depends if the need is to also see the heading indentation in edit mode or not. If not, then the DIVs could be generated only by the standard HTML Renderer for view (and not by the Annotated HTML Renderers).

It would of course be nice to have the edit mode be the same as the view mode. @mflorea Any idea how to achieve this without using DIVs?

Indeed, we would need to fix this. Adds to the cost.

@mleduc / @MichaelHamann would this break these extensions?

First of all, I think we should not use <div> but <section> elements.

I don’t think we still expect headings to be directly under the content wrapper, at least not for displaying the numbers. However, this will probably completely break resetting numbers as each manual number will only be valid in its section, e.g., when you reset the number of a heading 2, the next heading 2 will be in a different section container and thus not see the reset. The only way to fix this with CSS that I can think of is to drop support for Safari such that we can set counters instead of defining new ones.

Just as a side node, I’m not sure how relevant this is, this will also mess with the BodyFilter in our HTML cleaner that wraps certain content in paragraphs if it is directly below the <body>-tag. However, WikiModel should independently wrap content in paragraphs if it is not wrapped accordingly, so probably not that big of an issue.

Indeed, good point, I did not know about that one :slight_smile:

I think it’s possible with CSS indentation - CSS - successive indenting of siblings after headings - Stack Overflow .

Doesn’t work for me. You should definitely use px instead of em, but even then the result of using

* {
  margin: 0;
}
h1 ~ *:not(h1) {
  margin-left: 20px;
}
h2 ~ *:not(h1):not(h2) {
  margin-left: 40px;
}
h3 ~ *:not(h1):not(h2):not(h3) {
  margin-left: 60px;
}
h4 ~ *:not(h1):not(h2):not(h3):not(h4) {
  margin-left: 80px;
}
h5 ~ *:not(h1):not(h2):not(h3):not(h4):not(h5) {
  margin-left: 100px;
}
h6 ~ *:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6) {
  margin-left: 120px;
}

looks like

image

What about this:

#xwikicontent {
  counter-reset: indent;
}

#xwikicontent > h1:before {
  counter-set: indent 0;
}

#xwikicontent > h2:before {
  counter-set: indent 1;
}

#xwikicontent > h3:before {
  counter-set: indent 2;
}

#xwikicontent > h4:before {
  counter-set: indent 3;
}

#xwikicontent > h5:before {
  counter-set: indent 4;
}

#xwikicontent > h6:before {
  counter-set: indent 5;
}

@counter-style empty {
  system: cyclic;
  symbols: '';
}

@counter-style indent {
  system: symbolic;
  symbols: '\00a0';
  fallback: empty;
}

#xwikicontent > *:before {
  content: counter(indent, indent);
  font-family: monospace;
  font-size: 14pt;
}

I tested with Firefox and Chrome. Be aware that it might not work in Safari or IE.

Hope this helps,
Marius

Wow, Marius,

I currently don’t understand how, but it works with Chrome. With Safari it doesn’t, which is a pity, since I would like to keep the option to switch back to Safari. IE would be a must. I’ll check on Monday…

Best regards

Guido

… but even there has some funny side effects on floating elements