Do it all in Javascript.

Issue #90 new
Scott Selberg created an issue


I'm supporting a large corporate instance of Confluence, and we're merging in a smaller instance. The smaller instance has the numbered headings macro, so I'm poking at it a bit to understand how it's being using and deciding what potential risks are with it.

In general, I like the concept - but I'm a but curious about the implementation. When I first saw the macro, I assumed that javascript was inserting the numbering into the heading blocks - and the numbering was being saved into the confluence page. So when rendering, there was nothing for the macro to do. However, in looking at the code I see that there are two implementations. One in javascript which is active in the tinymce editor and once in java when rendering the page.

So, what would you think about a re-write of this macro where numbering was done exclusively in the editor and then saved into the storage body. i.e. instead of adding a class to place the numbering in the browser as the page renders, a <span> element is inserted with the numbering.

I could see this working in two ways. First, a bodyless macro that can activate the functionality and provide settings for the entire tinymce window. A macro just like the one you have created that only number/renumbers content in the body of hte macro.

What problems do you see with that approach?

Comments (7)

  1. Tomas Theunissen

    Hi Scott,

    You don't see it often that people actually check add-ons (or any other code people just run..) to see what they are actually doing, good work!

    To give a bit of context. The add-on was originally created with the Java implementation, when Confluence only had wiki markup and nothing like the editor right now. Since Confluence 4 we have the rich text editor and we got the idea to give the user some feedback by numbering the headings live in the editor. We had to use JavaScript for this. Thus we ended up with two implementations (actually three, since we have a closed source version for Confluence Cloud, although this one is also in JS based on the code in this repo).

    We have been discussing a rewrite (so we can move to a single JavaScript implementation as you suggest. Also to allow some more features) a couple of times internally and with Atlassian. There are a couple of reasons why we have not yet done the rewrite. Just a couple of them (it's been some time since we discussed this for the last time, so I don't remember every detail at the moment. And some stuff might have changed);

    • The numbering is also shown when exporting a page to a PDF or Word (or any other export that uses the correct API's). This is a lot harder to do when doing a JS only implementation. We discussed some stuff with showing the numbering with CSS, but this also had some limitations.
    • Currently the macro can number over multiple pages (and keep the correct numbering), when including pages or exporting pages (we keep state in the rendering thread which we can access at later invocations of the macro render method). A JS implementation makes this very hard if not impossible with the current way Confluence page rendering works.
    • We thought of a similar way to add the numbering information to the page, but then by adding a custom attribute (e.g. numbering="3.1"). But the Confluence editor removes all attributes except some that are whitelisted. Can't remember what the deal was with using something like a span, but there must have been something, since I cannot believe that we would not have considered that option.
    • We wanted to make the add-on completely macro-less and build a native experience (think Word, LibreOffice, ...). This makes things even harder.
    • Not really a technical reason, but Atlassian told us a couple of times that they are working on their own implementation. So we decided not to invest a lot of time anymore. But the last time Atlassian told us, is already more than half a year ago.

    I hope this answers your question. If you have any idea's on how to tackle some problems, we are all ears (or just to discuss them). I'll also inform @gerstree since he is the other (original) author of the add-on and discuss it with him when I speak him at the office.

  2. Scott Selberg reporter

    Seesh, just lost my last comment when I made an attachment.

    Anyway, I took a hack at it. It kind of works. You can see the code on the javascriptonly branch of this project:

    One note, there was some work to have the macro update the headings when the 'update.macro' event on the window fires. I think this event no longer exists. The functionality seems to be broken anyway.

    My version does have a new "Numbered Headings Full Page" which when present activates the functionality on the full window.

    When I used the include page macro for a page with the numbered headings - the numbers were discarded. Perhaps that something in the cloud version? (Looking at the source also seemed to indicate that the heading numbers would not be generated if the page was being "included")

  3. Scott Selberg reporter

    Just a few more thoughts before I head out.

    If using javascipt in the editor to insert numbers - the most of the time rending can just dump the contents. I could see that if the page was included, the rendering in Java may want to update the numbers positionally.

    As for activation for a page, I just dropped a bodyless macro on the page. In other use cases I've added a label to the page to activate functionality. I've also added a space category to activate the functionality. Just thoughts.

  4. Scott Selberg reporter

    OK, so I was toying with this in my head. Tell me what you think of this approach:

    The plugin provides three macros: Numbered Headings On This Page, Numbered Headings Section and Include Page with Re-Numbered Headings.

    The first plugin, Numbered Headings On This Page, would use javascript to insert the headings as span tags with a custom class (to identify the spans as being a heading descriptor). It would be nice to add a new "Start Numbering From" value of "Previous Page". I would expect when "Previous Page" is set, the javascript would make a rest request to call a routine which would locate the previous sibling or parent, see if that page has an instance of the "Numbered Headings On This Page" macro and if so figure out the number the last heading as the starting point for the numbering.

    The second macro, Include Page with Renumbered Headings would do just that. A bodyless macro that has all of the same parameters as the Numbered Heading macro and uses the Java based numbering code to re-write all of the span tags per the parameters in the macro body.

    The last macro, Numbered Headings Section is pretty much what you have today; however, it might be good to deprecate the ability to continue numbering from a previous instance of the macro on the page or from a previous page when exporting. My reasoning for this is it's confusing to see one numbering on the web and another when exporting to word or pdf. By using the Numbered Headings On This Page macro with the Previous Page option for Starting Numbering At, you effectively get the same behavior - but it works online too.

    One of the traps to watch out for is if a page has both a Numbered Headings On This Page and a Numbered Headings Section. I think the Numbered Headings Section should take priority and those headings ignored by the Numbered Headings On This Page.

    Oh, and I think it would be really nice to add in the macro properties for the start at heading (like the status macro where you can click on the macro and select the color without opening up the macro editor. I recently was playing with that code and it's pretty easy to implement.)

  5. Log in to comment