diff --git a/src/main/java/org/olat/core/gui/components/AbstractComponent.java b/src/main/java/org/olat/core/gui/components/AbstractComponent.java index d5d4179d613d53374426246b159cbd966c9592ac..77eaf2d7fe504a49eef05d35f668a6d1dc9dd9c0 100644 --- a/src/main/java/org/olat/core/gui/components/AbstractComponent.java +++ b/src/main/java/org/olat/core/gui/components/AbstractComponent.java @@ -64,6 +64,7 @@ public abstract class AbstractComponent implements Component { // true when contents have changed since last rendering private boolean dirty = false; private boolean domReplaceable = true; + private boolean domReplacementWrapperRequired = true; private final List<ComponentEventListener> listeners; private Translator translator; @@ -410,6 +411,18 @@ public abstract class AbstractComponent implements Component { return this.spanReplaceable; } + /** + * @return true: component does not print DOM ID on element; false: + * component always outputs an element with the dispatch ID as DOM + * ID + */ + public boolean isDomReplacementWrapperRequired() { + return this.domReplacementWrapperRequired; + } + public void setDomReplacementWrapperRequired(boolean domReplacementWrapperRequired) { + this.domReplacementWrapperRequired = domReplacementWrapperRequired; + } + /** * to be called only by the container when a child is added * @param parent diff --git a/src/main/java/org/olat/core/gui/components/Component.java b/src/main/java/org/olat/core/gui/components/Component.java index b96f114a43e2b66eb3b7bfc3c141ee9ae7b370d2..a60e5eee07c5509c96f501db2b8d3d249cda12b2 100644 --- a/src/main/java/org/olat/core/gui/components/Component.java +++ b/src/main/java/org/olat/core/gui/components/Component.java @@ -92,4 +92,11 @@ public interface Component { public Event getAndClearLatestFiredEvent(); + /** + * @return true: component does not print DOM ID on element; false: + * component always outputs an element with the dispatch ID as DOM + * ID + */ + public boolean isDomReplacementWrapperRequired(); + } \ No newline at end of file diff --git a/src/main/java/org/olat/core/gui/components/link/Link.java b/src/main/java/org/olat/core/gui/components/link/Link.java index 28451b0a7c2ae1ca19d91c54fbb478f78fe37626..41d32a28a6d616b0d7bf44dd0a7d99af3f74a599 100644 --- a/src/main/java/org/olat/core/gui/components/link/Link.java +++ b/src/main/java/org/olat/core/gui/components/link/Link.java @@ -153,10 +153,12 @@ public class Link extends AbstractComponent { + " component: " + getComponentName() + " dispatchId: " + getDispatchID()); } - setElementId("o_lnk"+getDispatchID()); // use span wrappers - if the custom layout needs div wrappers this flag has // to be set manually setSpanAsDomReplaceable(true); + // Directly use the dispatch ID for DOM replacement to minimize DOM tree + setElementId(getDispatchID()); + setDomReplacementWrapperRequired(false); } /** diff --git a/src/main/java/org/olat/core/gui/components/link/LinkRenderer.java b/src/main/java/org/olat/core/gui/components/link/LinkRenderer.java index fbaff504acfbac8443ee1c73b36bba4be0ffec58..a050eb7cdd439a789e599d3a808817fd48ce553a 100644 --- a/src/main/java/org/olat/core/gui/components/link/LinkRenderer.java +++ b/src/main/java/org/olat/core/gui/components/link/LinkRenderer.java @@ -252,6 +252,8 @@ public class LinkRenderer extends DefaultComponentRenderer { text = translator.translate(i18n); } sb.append("<span "); + if (elementId != null) sb.append(" id=\"").append(elementId).append("\" "); + String description = link.getTextReasonForDisabling(); // fallback to title if (description == null) description = link.getTitle(); diff --git a/src/main/java/org/olat/core/gui/control/generic/closablewrapper/CloseableCalloutWindowController.java b/src/main/java/org/olat/core/gui/control/generic/closablewrapper/CloseableCalloutWindowController.java index 03ad6ec8d1d79e44abc21574bcd6af067c02a776..bac816bab9d8d05ca0467c9973e5a1ce6fc74e3c 100644 --- a/src/main/java/org/olat/core/gui/control/generic/closablewrapper/CloseableCalloutWindowController.java +++ b/src/main/java/org/olat/core/gui/control/generic/closablewrapper/CloseableCalloutWindowController.java @@ -137,8 +137,7 @@ public class CloseableCalloutWindowController extends BasicController { public CloseableCalloutWindowController(UserRequest ureq, WindowControl wControl, Component calloutWindowContent, Link targetLink, String title, boolean closable, String cssClasses) { - this(ureq, wControl, calloutWindowContent, "o_lnk" - + targetLink.getDispatchID(), title, closable, cssClasses); + this(ureq, wControl, calloutWindowContent, targetLink.getDispatchID(), title, closable, cssClasses); } /** diff --git a/src/main/java/org/olat/core/gui/render/Renderer.java b/src/main/java/org/olat/core/gui/render/Renderer.java index e9ef3619a808c49d989e6fa2778cabc929db8e58..0f2c2846c28787f57d1bc14c1a466cefb24b7a31 100644 --- a/src/main/java/org/olat/core/gui/render/Renderer.java +++ b/src/main/java/org/olat/core/gui/render/Renderer.java @@ -201,7 +201,8 @@ public class Renderer { // wrap with div's so javascript can replace this component by doing a document.getElementById(cid).innerHTML and so on. boolean domReplaceable = source.isDomReplaceable(); boolean useSpan = source.getSpanAsDomReplaceable(); - boolean forceDebugDivs = gset.isIdDivsForced(); + boolean domReplacementWrapperRequired = source.isDomReplacementWrapperRequired(); + boolean forceDebugDivs = gset.isIdDivsForced(); if (source.isVisible()) { int lev = renderResult.getNestedLevel(); @@ -210,7 +211,7 @@ public class Renderer { // for ajax mode: render surrounding divs or spans as a positional // identifier for dom replacement - if (domReplaceable && (ajaxon || forceDebugDivs)) { + if (domReplaceable && domReplacementWrapperRequired && (ajaxon || forceDebugDivs)) { if (useSpan) { sb.append("<span id=\"o_c").append(source.getDispatchID()).append("\">"); } else { @@ -272,7 +273,7 @@ public class Renderer { // close div for the javascript dom replacement - if (ajaxon && domReplaceable) { + if (ajaxon && domReplaceable && domReplacementWrapperRequired) { if(useSpan){ sb.append("</span>"); } else{