Idea: Moving Content Indicator

Hi Guys,

this is more a request for a feature:

I use Xwiki for documentation which often leads to massive Content within one Page.
I really love the content-macro to display all the headlines. The only problem for me is
the effort of scrolling back to the top of the page just to reach the macro again.

How much effort would it be -or better - which approach could i take to make that macro moving with
the top corner of the page?

That would be dope!

Cheers,
Tom

head_7
Like this…

Hi, what macro is this? It’s not used to display headlines (if you’re talking about https://extensions.xwiki.org/xwiki/bin/view/Extension/Content%20Macro).

I dont know the english name cause the macros are labled in german. But actually you can see which macro i mean in the gif? This macro makes a visuzal content-index according to “headlined” words. What you see in the gif is a slightly changed version of the original Encyclopedia template…i just “animated” my idea…

I don’t see anything in the GIF and I have no idea what macro you’re talking about.

Can you give me the link to the extension from https://extensions.xwiki.org?

Edit your page in wiki mode and you’ll see the macros used.

Again, the whole macro is described in german.there is no hint, how the extension could be called in english.
The information i can provide is that:

A) the html code for the macro is {{toc/}}
B) Its part of the encyclopedia template which is a standard i guess?(righthand side under Avatarpic)
C) its shown in the gif on the right side under the avatarpic.

That template is the default “Simple Page” one and uses this snippet:

{{box cssClass="floatinginfobox" title="**Contents**"}}
{{toc/}}
{{/box}}

Which is equivalent to

(% class="box" %)
(((
**Contents**

{{toc/}}
)))

in the encyclopedia template.

I’d thought about this too, but the hovering TOC would get in the way of content further below.
Maybe this is possible by manipulating css? Since floatinginfobox is a cssclass too.

I thought about pinning the content in the left or right sidebar panels of xwiki instead. This would be nice to have independently of a TOC.
I have yet to find out how to display a TOC in a Panel which uses the currently viewed page as a reference :slight_smile:

Yes it’s not easy, see Loading...

A bit late but here is my quick solution to your question.

Basically what I do is wrap the TOC inside a box and apply some JSX and SSX. Hackish but it does the job.

Feel free to adapt and optimize.

TOC

{{box cssClass="floatinginfobox pagetoc" title="**Content**"}}
{{toc numbered="true"/}}
{{/box}}

JSX

window.onload = function myFunction() {
  // Get the TOC
  var elements = document.getElementsByClassName("pagetoc");
  // When the user scrolls the page, execute myFunc
  window.onscroll = function myFunc() {
    // Get the offset position of the content container
    var element = document.getElementById("xwikicontent");
    var icon = document.getElementById("toc-icon");
    var sticky = element.offsetTop;
    // Add the sticky class to the TOC when you reach the scroll position. Remove "sticky" when you leave the scroll position
    if (window.pageYOffset >= sticky) {
      elements[0].classList.add("toc-sticky");
      if (icon == null) {
        elements[0].innerHTML += `<i id="toc-icon"></i>`;
        var t = document.getElementById("toc-icon");
        t.addEventListener("click", function iToggle() {
          var elements = document.getElementsByClassName("pagetoc");
          if (elements[0].classList.contains('toc-sticky-expanded')) {
            elements[0].classList.remove("toc-sticky-expanded");
          } else {
            elements[0].classList.add("toc-sticky-expanded");
          }
        });
      }
    } else {
      elements[0].classList.remove("toc-sticky");
      elements[0].classList.remove("toc-sticky-expanded");
      if (icon != null) {
        icon.remove();
        icon.removeEventListener("click", iToggle)
      }
    }
  };
};

SSX

.toc-sticky {
  display: block;
  overflow: hidden;
  position: fixed;
  z-index: 10;
  top: 20px;
  width: 35px;
  height: 35px;
  padding: 0;
  margin-top: 30px;
}

.toc-sticky-expanded {
  width: 50% !important;
  height: auto;
  overflow: hidden;
  padding: 14px 37px 32px 37px;
}

.toc-sticky-expanded #toc-icon {
    border-right: 1px solid rgba(0, 0, 0, 0.15);
    border-bottom: 1px solid rgba(0, 0, 0, 0.15);
    padding: 10px 12px;
    background-image: none;
    width: 35px;
    height: 35px;
    background-image: url(SOME IMAGE);
    background-size: 44px;
    background-repeat: no-repeat;
    background-position: -5px -5px;
}

#toc-icon {
    top: 0;
    left: 0;
    position: absolute;
    z-index: 100;
    color: rgba(0, 0, 0, 0.7);
    cursor: pointer;
    width: 35px;
    height: 35px;
    background-image: url(SOME IMAGE);
    background-size: 44px;
    background-repeat: no-repeat;
    background-position: -5px -5px;
}

Hey Pako!
It looks like you have created a nice solution for a problem, which i also like to solve. My only problem is, that i don’t know much about XWiki and Java, because i’m new to it and i do not know exactly, how i can implement your solution. The TOC Code is already working in the page, but i don’t know where to insert the JSX and SSX Code. I hope you can help me with that.
Thank you very much in advance!

With kind regards,
Burny

Thanks. Extending certain pages or the whole Wiki with CSS and JS is pretty easy and straightforward. Here are some screenshots for you.

Please also take a look at the documentation: https://www.xwiki.org/xwiki/bin/view/Documentation/DevGuide/Tutorials/SkinExtensionsTutorial/

Add TOC to page

Should be rendered something like this

Navigate to object editor

Add JSX; paste code

Add SSX; paste code

You should end up with a minimized and sticky TOC as soon as you reach the predefined offset position

Positioning and styling are up to your preferences of course.

Hey Pako,
that worked exactly like you have shown me here.
Thank you very much for your help and your solution, that was really nice!
Have a nice day!

Best regards,
Burny