Proposal: Add an UIXP for the end of the DOM

Hi!

Proposal

Implement a new UIXP named org.xwiki.platform.template.body.end to gather elements that should be placed at the end of the DOM. The UIXs should handle their own styles and be invisible by default
This UIXP’s idea is described with more detail on the jira ticket XWIKI-23129: Add an end of DOM UIXP

Explanation

Right now, we have modal elements hanging around a bit everywhere in the DOM. Most of them are already loosely placed at the end of the DOM. Modals can handle their own positioning and layout wherever they are in the DOM and are invisible by default. Adding an UIXP gives devs a new way to easily place an invisible element in the DOM without risking it interfering with the main content they are providing. For example, in XWIKI-22996 the modal interefered with the accessibility of its parent list (and there was no clean way to move this modal somewhere safe).

Opinion

I’m +1 for the creation of this UIXP. It should be straightforward to implement into any Skin because it’s quite a low level of abstraction (definition based on HTML concepts and not Flamingo specific concepts).

Conclusion

Do you agree with adding this UIXP to Xwiki Standard?

You can check out a proposal of implementation and a couple basic uses at XWIKI-23129: Add an `end of DOM` UIXP by Sereza7 · Pull Request #4085 · xwiki/xwiki-platform · GitHub :slight_smile:

Thank you for your interest in the topic!
Lucas C.

1 Like

+1 for having the UIXP. Right now it’s mainly for modals in XS but I’m sure it could have other usages too.

I’m not sure I understand what a “modal element” is. I’ve checked what we have just before the closing </body> and I see:

<div class="clearfloats"></div>
  </div></div><footer id="footerglobal">
  <div id="xwikilicence"></div>
            <div id="xwikiplatformversion">
                    <a href="https://extensions.xwiki.org?id=org.xwiki.platform:xwiki-platform-distribution-jetty-hsqldb:16.10.8:::/xwiki-commons-pom/xwiki-platform/xwiki-platform-distribution/xwiki-platform-distribution-jetty-hsqldb">
                XWiki Jetty HSQLDB 16.10.8
              </a>
          </div>
  </footer>

</div></div></body>

What will the UIXP do precisely? What does “at the end of the DOM” mean?

If this is about inserting javascript, why wouldn’t a <script defer> work?

Sorry for the noob questions

Note that nothing is straightforward :slight_smile: If this UIXP controls important features of XS then as soon as you add it, then it means that suddenly XWiki gets broken when using lots of existing skins on e.x.o (or custom ones). The case where it’ll work is probably if these skin extend the Flaming one.

In other words, we’re breaking backward compatibility and the skins need to be updated to continue working with the latest version of XWiki. Now in practice, it’s not like we were good on this topic and it’s not the first important UIXP we’re adding. It still is a topic that we need to discuss for the future.

If the UIXP implementation is not located in the skin then we should question if a UIXP is the right concept. We could as well have a component for it if it’s in Java. Or use a Skin Extension (js*x) if it’s javascript.

Globally I want to make sure we have no other way of doing what you need.

Found my answer at XWIKI-23129: Add an `end of DOM` UIXP by Sereza7 · Pull Request #4085 · xwiki/xwiki-platform · GitHub

So I see this as potentially encapsulating our js*x since they add <script defer> in the HEAD which I understand is the same as putting them just before the </body>, right?

So it’ll mean two ways of doing this AFAIU.

Does it mean a end-of-DOM UIXP should remove / deprecate the need for JSX?

Any extension/customization could use it for its other modals. Not sure whether there is another kind of element that would make sense to put in there, but it would be there in case the standard evolves and more uses pop up.

It’s pretty much a dialog element, using the HTML standard definition. A modal is a dialog that takes all the focus (it makes sense to hide all the main content while the modal is open).

I’m not sure where you got this DOM, the one I get on my local XS instance is more messy:


Ignore the .modal-container div, this one is related to a customization I have on here.

It’s about inserting invisible elements that get activated by javascript. In most cases, it will be modals, or things that should be modals. I added to the proposal strong expectations on the UIXs so that it doesn’t get misused. By default, nothing should be shown, and the UIXs are responsible of “showing” themselves whenever needed and how they are positioned/laid out. The UIX is pretty much just a box to put misc things into, it doesn’t hold any responsibility.

Okay :slight_smile:

Thank you for the explanation, the implications are clearer to me now. Ideally we’ll move all the XS modals in here, not sure how many of those are defined outside of Flamingo. There are definitely some in Flamingo. E.g. The export modal at xwiki-platform/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/export_modal.vm at master · xwiki/xwiki-platform · GitHub and xwiki-platform/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/uicomponents/exporter/exporter.js at 6bbb277528374f801a3c256fd281234db844d9bb · xwiki/xwiki-platform · GitHub is currently quite difficult to make for other skins. Moving it inside a UIX would make it more reusable.

In a word, there’s problems with alternative skin compatibility, but it would also make some things easier :slight_smile:

I don’t think we want to change anything we do about JSX in XS. The current way works, it’s a tested and tried feature and that would be a shame to change things without a good reason. I think there must be a good reason why we don’t just add JSX on the existing UIXP org.xwiki.platform.html.head https://www.xwiki.org/xwiki/bin/view/Documentation/DevGuide/ExtensionPoint/HTMLHead and this reason would probably apply for org.xwiki.platform.template.body.end too

Dialog/modals cannot be put in the head, contrary to scripts, so it’s useful to have somewhere to inject them at. We did XWiki for years without this UIXP so technically it’s possible to do without it, but I think it’s making things easier for ourselves later to organize this HTML a bit. XWIKI-22996 can be solved in other ways, but the other ways look like workarounds (more tech debt) because we don’t have the proper UIXP so I figured it’d make sense to propose adding one :slight_smile:

I can think of one simple explanation: the Stylesheet Extension mechanism predates the UIXP mechanism :slight_smile:

Now the Stylesheet Extension (SX) mechanism is currently way easier to use in Java than UIX. In wiki pages they are about the same, both require an xobject to be filled. In java, for UIX you need to create a component and handle the triggering (when “on demand”) which is not easy. Much simpler for SX.

I still think we need to have a discussion about this topic.

BTW I’m 100% sure we need an order for this end of DOM UIXP. Not for your use case but for the generic need. As soon as you use it to display stuff, you need an order. And even for non-visible things you may also need an order.

What is a style? Also what does it mean to be invisible by default (when does it become visible)?

Also, the following indicates that it can be used to display stuff:

By “showing themselves” you mean they’re responsible for their rendering, right?

I don’t know enough about modals and alternative explanations so I’m +0 ATM.

Last, I’m pretty sure that once we introduce it, at some point, we’ll want a start-of-the-DOM UIXP too… It’s logical. :slight_smile:

Thx

AFAIU, most UIXP want an order because they are responsible for finding the position and most of the time size of the UIXs. Here, at least for the first use case, we don’t need to take these responsibilities (most of it is handled by the browser for dialogs natively), so I propose to make it clear and not support an order since we don’t need it. Is there an issue to adding the order later to the UIX if and when we’ll need it in XS?

For example, they should handle how they are positioned on the screen and how large they are.
Being invisible by default is the default for dialogs. You need to call the javascript dialog.show() to display it (doc) But it can also be any custom element with the CSS display: none or anything similar.

The UIXP is not involved in triggering the activation of the UIXs, they should all be independent. Typically I expect a lot of them to come with a simple JSX that opens the modal when a button is clicked and also handles the interactivity of the UI in the modal if there’s any need.

Stuff inside it is displayed independently of the container. It could be pretty much anywhere in the DOM and display the same. That’s something that is true for modals (here is a quick demo on codepen)and that makes maintenance easier if we assume this property is here for all UIX. This UIXP is quite barebones, but we don’t need much for our current use case so I don’t think it’s worth troubling ourselves with more.

As far as I can see, there’s no misc elements before the #xwikimaincontainer, and any of the kind of elements we’d want to put at this level do not care where they are in the DOM, so they might as well be at the end of the body just as well as the beginning. I don’t think we’ll have a need for a start of the DOM UIXP as long as we don’t use the current one to sort script priorities (which IMO should not happen), But anyways, I guess we’ll see and add a second UIXP if we need it in the future.

No, an order is needed because the UIXs can display something.

This UIXP is not about modals/dialogs at all :grinning: It’s about HTML you can have before the closing BODY tag. The name of the UIXP reflects that.

Yet it is since it calls execute() on the UIX and thus renders them.

This is clearly not true. There are lots of elements that need to be in the HEAD and putting them at the end of the BODY wouldn’t work.

+1

I thought we could make some expectations on what the UIXs provide, and that as long as we say that UIXs should not display anything by default and handle how they get displayed themselves in the documentation, we can implement the UIXP by assuming they would respect the expectations.
E.g. The tips panel UIXP expects text in the tip parameter. If a user provides HTML in the content of the UIX, it’s not the responsibility of the UIXP to make sure everything works as the user imagines.

The place we inject those does not make sense in the layout (it’s after the footer…), so I don’t think there’s any way to support UIXs that do display something by default without it looking off. Modals and dialogs are kind of in their own layout, so this is the place where it makes the most sense to keep them IMO, even if pretty much anywhere could work.

We do implement it primarily to put modal/dialogs inside it. If we can’t agree on a way to make it generic, I think the best solution would be to just name it org.xwiki.platform.dialog.container and expect UIXs to only provide dialog HTML elements. I figured we didn’t really NEED the content to be a dialog, but just that it respects a few rules, so I proposed a generic name that would allow generic use cases (but not everything either).

By activation, I meant the equivalent for the content to a HTML dialog’s show() or showModal() calls. The UIXP will render the UIXs and put them in the DOM, maybe it will even create the <script> tag with the eventHandler that will trigger this show() function, but it will not show all the modals at the start of the page.

I didn’t understand you were talking about HEAD elements. We already have a UIXP for this: https://www.xwiki.org/xwiki/bin/view/Documentation/DevGuide/ExtensionPoint/HTMLHead


There’s both a bunch of HTML in the HEAD and at the end of the BODY (at the end = after #xwikimaincontainer which itself contains everything visible from the header to the footer), but there’s nothing at the start of the BODY (before #xwikimaincontainer) yet.

We can definitely have that expectation but only if we say that the UIXs must not display anything at all (ie no visual HTML tags). We cannot say that they shouldn’t display anything by default since that implies that they can display something from time to time…

Again you’re talking about modals but the UIXP is generic and not related to modals… This is why I couldn’t understand what you meant by “activation” in the context of this generic UIXP.

Thx for the link, I wasn’t aware we had this. BTW this UIXP is very badly defined in the doc as it doesn’t say where the UIX are inserted. It just says inside the HEAD but we don’t know where: at the beginning, at the end, in the middle, etc. The screenshot even makes it worse since it shows some place in the middle fo the metadata tags…

I was more talking about a UIXP to add stuff at the beginning of the DOM (ie at the top of the HEAD for ex, or at the end of the HEAD) and end of the DOM (ie at the end of the BODY). But it seems we already have it for the HEAD. I guess it could also be used instead of a JSX to add a SCRIPT tag too.

So I think I was having a hard time understanding you with the vocabulary used. You’re defining a generic UIXP but using words that make sense only for modals. We need the UIXP to be defined generically.

Thx