You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2022/03/02 13:56:17 UTC

[isis] branch master updated: ISIS-2877: properly wire up html rendering for Markup components

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new 4ae407f  ISIS-2877: properly wire up html rendering for Markup components
4ae407f is described below

commit 4ae407f7d1cb41c56f111a591d8280a9127370b8
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Mar 2 14:54:31 2022 +0100

    ISIS-2877: properly wire up html rendering for Markup components
---
 .../metamodel/facets/object/value/ValueFacet.java  | 19 ++++++++++-
 .../interactions/managed/_BindingUtil.java         | 24 ++++++++------
 .../isis/core/metamodel/spec/ManagedObject.java    | 37 +++++++++++++++++++---
 .../ui/wkt/components/AsciiDocComponentWkt.java    | 12 ++++++-
 .../wkt/components/AsciiDocPanelFactoriesWkt.java  | 19 ++++++-----
 .../ui/wkt/components/MarkdownComponentWkt.java    | 13 +++++++-
 .../wkt/components/MarkdownPanelFactoriesWkt.java  | 19 ++++++-----
 .../ui/wkt/markup/ListeningMarkupComponent.java    | 21 +++++++++---
 .../ListeningMarkupPanelFactoriesForWicket.java    | 31 ++++++++----------
 .../viewer/wicket/model/models/ValueModel.java     |  3 +-
 .../components/scalars/markup/MarkupComponent.java | 13 ++++++--
 .../scalars/markup/MarkupComponentFactory.java     |  4 +--
 .../scalars/markup/MarkupPanelFactories.java       | 22 ++++++-------
 .../scalars/markup/ParentedMarkupPanel.java        |  6 ++--
 .../scalars/markup/StandaloneMarkupPanel.java      |  6 ++--
 .../ui/components/tree/TreePanelFactories.java     |  3 +-
 16 files changed, 168 insertions(+), 84 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueFacet.java
index 5823618..c8519cb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/ValueFacet.java
@@ -78,7 +78,10 @@ extends
     Optional<Parser<T>> selectParserForParameter(final ObjectActionParameter param);
     Optional<Parser<T>> selectParserForProperty(final OneToOneAssociation prop);
 
-    default Optional<Parser<T>> selectParserForFeature(final ObjectFeature feature) {
+    default Optional<Parser<T>> selectParserForFeature(final @Nullable ObjectFeature feature) {
+        if(feature==null) {
+            return selectDefaultParser();
+        }
         switch(feature.getFeatureType()) {
         case ACTION_PARAMETER_SCALAR:
             return selectParserForParameter((ObjectActionParameter)feature);
@@ -115,6 +118,20 @@ extends
 
     Renderer<T> fallbackRenderer(Identifier featureIdentifier);
 
+    default Optional<Renderer<T>> selectRendererForFeature(final @Nullable ObjectFeature feature) {
+        if(feature==null) {
+            return selectDefaultRenderer();
+        }
+        switch(feature.getFeatureType()) {
+        case ACTION_PARAMETER_SCALAR:
+            return selectRendererForParameter((ObjectActionParameter)feature);
+        case PROPERTY:
+            return selectRendererForProperty((OneToOneAssociation)feature);
+        default:
+            return selectDefaultRenderer();
+        }
+    }
+
     default Renderer<T> selectRendererForParameterElseFallback(final ObjectActionParameter param) {
         return selectRendererForParameter(param)
                 .orElseGet(()->fallbackRenderer(param.getFeatureIdentifier()));
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java
index e598489..cca181e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java
@@ -64,11 +64,14 @@ class _BindingUtil {
 
         // value types should have associated parsers/formatters via value semantics
         return spec.lookupFacet(ValueFacet.class)
-        .map(valueFacet->format.requiresRenderer()
+        .map(valueFacet->{
+            val eitherRendererOrParser = format.requiresRenderer()
                 ? _Either.<Renderer, Parser>left(valueFacet.selectRendererForPropertyElseFallback(prop))
-                : _Either.<Renderer, Parser>right(valueFacet.selectParserForPropertyElseFallback(prop)))
-        .map(eitherRendererOrParser->
-                bindAsFormated(format, spec, bindablePropertyValue, eitherRendererOrParser, null))
+                : _Either.<Renderer, Parser>right(valueFacet.selectParserForPropertyElseFallback(prop));
+            val ctx = valueFacet.createValueSemanticsContext(prop);
+
+            return bindAsFormated(format, spec, bindablePropertyValue, eitherRendererOrParser, ctx);
+        })
         .orElseGet(()->
             // fallback Bindable that is floating free (unbound)
             // writing to it has no effect on the domain
@@ -90,11 +93,14 @@ class _BindingUtil {
 
         // value types should have associated parsers/formatters via value semantics
         return spec.lookupFacet(ValueFacet.class)
-        .map(valueFacet->format.requiresRenderer()
+        .map(valueFacet->{
+            val eitherRendererOrParser = format.requiresRenderer()
                 ? _Either.<Renderer, Parser>left(valueFacet.selectRendererForParameterElseFallback(param))
-                : _Either.<Renderer, Parser>right(valueFacet.selectParserForParameterElseFallback(param)))
-        .map(eitherRendererOrParser->
-                bindAsFormated(format, spec, bindableParamValue, eitherRendererOrParser, null))
+                : _Either.<Renderer, Parser>right(valueFacet.selectParserForParameterElseFallback(param));
+            val ctx = valueFacet.createValueSemanticsContext(param);
+
+            return bindAsFormated(format, spec, bindableParamValue, eitherRendererOrParser, ctx);
+        })
         .orElseGet(()->
             // fallback Bindable that is floating free (unbound)
             // writing to it has no effect on the domain
@@ -142,7 +148,7 @@ class _BindingUtil {
             final @NonNull ObjectSpecification spec,
             final @NonNull _BindableAbstract<ManagedObject> bindableValue,
             final @NonNull _Either<Renderer, Parser> eitherRendererOrParser,
-            final Context context) {
+            final @NonNull Context context) {
 
         switch (format) {
         case TITLE: {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
index 2264b45..3365434 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
@@ -26,6 +26,7 @@ import java.util.function.UnaryOperator;
 import org.springframework.lang.Nullable;
 
 import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.value.semantics.Renderer;
 import org.apache.isis.commons.internal.assertions._Assert;
 import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.commons.internal.collections._Collections;
@@ -34,7 +35,9 @@ import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facets.object.icon.ObjectIcon;
 import org.apache.isis.core.metamodel.facets.object.title.TitleRenderRequest;
+import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
 import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
+import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 
 import lombok.AccessLevel;
@@ -144,15 +147,43 @@ public interface ManagedObject {
         //_Assert.assertEquals(spec, actualSpec);
     }
 
+    // -- HTML
+
+    public default String htmlString(
+            final @Nullable ObjectFeature feature) {
+
+        if(getSpecification()==null) {
+            return "";
+        }
+
+        val spec = getSpecification();
+        val valueFacet = spec.getFacet(ValueFacet.class);
+
+        if(valueFacet==null) {
+            return String.format("missing ValueFacet %s", spec.getCorrespondingClass());
+        }
+
+        final Renderer renderer = (Renderer) valueFacet.selectRendererForFeature(feature).orElse(null);
+        if(renderer==null) {
+            return String.format("missing Renderer %s", spec.getCorrespondingClass());
+        }
+
+        return renderer.htmlPresentation(valueFacet.createValueSemanticsContext(feature), this.getPojo());
+    }
+
     // -- TITLE
 
     public default String titleString(final UnaryOperator<TitleRenderRequest.TitleRenderRequestBuilder> onBuilder) {
         return ManagedObjects.TitleUtil
-                .titleString(onBuilder.apply(TitleRenderRequest.builder().object(this)).build());
+                .titleString(onBuilder.apply(
+                        TitleRenderRequest.builder()
+                        .object(this))
+                        .build());
     }
 
     public default String titleString() {
-        return ManagedObjects.TitleUtil.titleString(TitleRenderRequest.builder()
+        return ManagedObjects.TitleUtil.titleString(
+                TitleRenderRequest.builder()
                 .object(this)
                 .build());
     }
@@ -431,6 +462,4 @@ public interface ManagedObject {
     }
 
 
-
-
 }
diff --git a/valuetypes/asciidoc/ui/wicket/src/main/java/org/apache/isis/valuetypes/asciidoc/ui/wkt/components/AsciiDocComponentWkt.java b/valuetypes/asciidoc/ui/wicket/src/main/java/org/apache/isis/valuetypes/asciidoc/ui/wkt/components/AsciiDocComponentWkt.java
index 61419a6..209b929 100644
--- a/valuetypes/asciidoc/ui/wicket/src/main/java/org/apache/isis/valuetypes/asciidoc/ui/wkt/components/AsciiDocComponentWkt.java
+++ b/valuetypes/asciidoc/ui/wicket/src/main/java/org/apache/isis/valuetypes/asciidoc/ui/wkt/components/AsciiDocComponentWkt.java
@@ -27,6 +27,8 @@ import org.apache.wicket.model.IModel;
 import org.apache.wicket.request.resource.ResourceReference;
 
 import org.apache.isis.valuetypes.prism.wkt.PrismResourcesWkt;
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.model.models.ValueModel;
 import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponent;
 import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponent_reloadJs;
 
@@ -36,7 +38,15 @@ public class AsciiDocComponentWkt extends MarkupComponent {
 
     private static final long serialVersionUID = 1L;
 
-    public AsciiDocComponentWkt(final String id, final IModel<?> model) {
+    public AsciiDocComponentWkt(final String id, final ScalarModel model){
+        super(id, model);
+    }
+
+    public AsciiDocComponentWkt(final String id, final ValueModel model){
+        super(id, model);
+    }
+
+    public AsciiDocComponentWkt(final String id, final IModel<String> model){
         super(id, model);
     }
 
diff --git a/valuetypes/asciidoc/ui/wicket/src/main/java/org/apache/isis/valuetypes/asciidoc/ui/wkt/components/AsciiDocPanelFactoriesWkt.java b/valuetypes/asciidoc/ui/wicket/src/main/java/org/apache/isis/valuetypes/asciidoc/ui/wkt/components/AsciiDocPanelFactoriesWkt.java
index 357e9a8..55900b0 100644
--- a/valuetypes/asciidoc/ui/wicket/src/main/java/org/apache/isis/valuetypes/asciidoc/ui/wkt/components/AsciiDocPanelFactoriesWkt.java
+++ b/valuetypes/asciidoc/ui/wicket/src/main/java/org/apache/isis/valuetypes/asciidoc/ui/wkt/components/AsciiDocPanelFactoriesWkt.java
@@ -21,7 +21,9 @@ package org.apache.isis.valuetypes.asciidoc.ui.wkt.components;
 import org.springframework.stereotype.Component;
 
 import org.apache.isis.valuetypes.asciidoc.applib.value.AsciiDoc;
-import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponentFactory;
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.model.models.ValueModel;
+import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponent;
 import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupPanelFactories;
 
 import lombok.val;
@@ -45,13 +47,10 @@ public class AsciiDocPanelFactoriesWkt {
         }
 
         @Override
-        protected MarkupComponentFactory getMarkupComponentFactory() {
-            return (id, model) -> {
-                val markupComponent = new AsciiDocComponentWkt(id, model);
-                markupComponent.setEnabled(false);
-                return markupComponent;
-            };
-
+        protected MarkupComponent newMarkupComponent(final String id, final ScalarModel model) {
+            val markupComponent = new AsciiDocComponentWkt(id, model);
+            markupComponent.setEnabled(false);
+            return markupComponent;
         }
 
     }
@@ -67,8 +66,8 @@ public class AsciiDocPanelFactoriesWkt {
         }
 
         @Override
-        protected MarkupComponentFactory getMarkupComponentFactory() {
-            return AsciiDocComponentWkt::new;
+        protected MarkupComponent newMarkupComponent(final String id, final ValueModel model) {
+            return new AsciiDocComponentWkt(id, model);
         }
 
     }
diff --git a/valuetypes/markdown/ui/wicket/src/main/java/org/apache/isis/valuetypes/markdown/ui/wkt/components/MarkdownComponentWkt.java b/valuetypes/markdown/ui/wicket/src/main/java/org/apache/isis/valuetypes/markdown/ui/wkt/components/MarkdownComponentWkt.java
index 8715899..fa873e8 100644
--- a/valuetypes/markdown/ui/wicket/src/main/java/org/apache/isis/valuetypes/markdown/ui/wkt/components/MarkdownComponentWkt.java
+++ b/valuetypes/markdown/ui/wicket/src/main/java/org/apache/isis/valuetypes/markdown/ui/wkt/components/MarkdownComponentWkt.java
@@ -27,6 +27,8 @@ import org.apache.wicket.model.IModel;
 import org.apache.wicket.request.resource.ResourceReference;
 
 import org.apache.isis.valuetypes.prism.wkt.PrismResourcesWkt;
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.model.models.ValueModel;
 import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponent;
 import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponent_reloadJs;
 
@@ -36,10 +38,19 @@ public class MarkdownComponentWkt extends MarkupComponent {
 
     private static final long serialVersionUID = 1L;
 
-    public MarkdownComponentWkt(final String id, final IModel<?> model) {
+    public MarkdownComponentWkt(final String id, final ScalarModel model){
         super(id, model);
     }
 
+    public MarkdownComponentWkt(final String id, final ValueModel model){
+        super(id, model);
+    }
+
+    public MarkdownComponentWkt(final String id, final IModel<String> model){
+        super(id, model);
+    }
+
+
     @Override
     public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) {
         val htmlContent = extractHtmlOrElse(getDefaultModelObject(), "" /*fallback*/);
diff --git a/valuetypes/markdown/ui/wicket/src/main/java/org/apache/isis/valuetypes/markdown/ui/wkt/components/MarkdownPanelFactoriesWkt.java b/valuetypes/markdown/ui/wicket/src/main/java/org/apache/isis/valuetypes/markdown/ui/wkt/components/MarkdownPanelFactoriesWkt.java
index ca69bda..9707fea 100644
--- a/valuetypes/markdown/ui/wicket/src/main/java/org/apache/isis/valuetypes/markdown/ui/wkt/components/MarkdownPanelFactoriesWkt.java
+++ b/valuetypes/markdown/ui/wicket/src/main/java/org/apache/isis/valuetypes/markdown/ui/wkt/components/MarkdownPanelFactoriesWkt.java
@@ -21,7 +21,9 @@ package org.apache.isis.valuetypes.markdown.ui.wkt.components;
 import org.springframework.stereotype.Component;
 
 import org.apache.isis.valuetypes.markdown.applib.value.Markdown;
-import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponentFactory;
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.model.models.ValueModel;
+import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponent;
 import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupPanelFactories;
 
 import lombok.val;
@@ -45,13 +47,10 @@ public class MarkdownPanelFactoriesWkt {
         }
 
         @Override
-        protected MarkupComponentFactory getMarkupComponentFactory() {
-            return (id, model) -> {
-                val markupComponent = new MarkdownComponentWkt(id, model);
-                markupComponent.setEnabled(false);
-                return markupComponent;
-            };
-
+        protected MarkupComponent newMarkupComponent(final String id, final ScalarModel model) {
+            val markupComponent = new MarkdownComponentWkt(id, model);
+            markupComponent.setEnabled(false);
+            return markupComponent;
         }
 
     }
@@ -67,8 +66,8 @@ public class MarkdownPanelFactoriesWkt {
         }
 
         @Override
-        protected MarkupComponentFactory getMarkupComponentFactory() {
-            return MarkdownComponentWkt::new;
+        protected MarkupComponent newMarkupComponent(final String id, final ValueModel model) {
+            return new MarkupComponent(id, model);
         }
 
     }
diff --git a/valuetypes/sse/ui/wicket/src/main/java/org/apache/isis/valuetypes/sse/ui/wkt/markup/ListeningMarkupComponent.java b/valuetypes/sse/ui/wicket/src/main/java/org/apache/isis/valuetypes/sse/ui/wkt/markup/ListeningMarkupComponent.java
index dc2ebba..15a99d7 100644
--- a/valuetypes/sse/ui/wicket/src/main/java/org/apache/isis/valuetypes/sse/ui/wkt/markup/ListeningMarkupComponent.java
+++ b/valuetypes/sse/ui/wicket/src/main/java/org/apache/isis/valuetypes/sse/ui/wkt/markup/ListeningMarkupComponent.java
@@ -22,10 +22,11 @@ import javax.inject.Inject;
 
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.MarkupStream;
-import org.apache.wicket.model.IModel;
 
 import org.apache.isis.applib.value.LocalResourcePath;
 import org.apache.isis.core.config.viewer.web.WebAppContextPath;
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.model.models.ValueModel;
 import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponent;
 
 import lombok.val;
@@ -38,11 +39,22 @@ public class ListeningMarkupComponent extends MarkupComponent {
     @Inject
     private WebAppContextPath webAppContextPath;
 
-    public ListeningMarkupComponent(final String id, IModel<?> model, LocalResourcePath observing){
+    public ListeningMarkupComponent(
+            final String id,
+            final ScalarModel model,
+            final LocalResourcePath observing){
         super(id, model);
         this.observing = observing;
     }
 
+    public ListeningMarkupComponent(
+            final String id,
+            final ValueModel model){
+        super(id, model);
+        this.observing = null;
+    }
+
+
     @Override
     public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag){
         val htmlContent = extractHtmlOrElse(getDefaultModelObject(), "" /*fallback*/);
@@ -51,11 +63,10 @@ public class ListeningMarkupComponent extends MarkupComponent {
                 openTag,
 
                 observing!=null
-                ? ListeningMarkupComponent_observing.decorate(htmlContent, observing, webAppContextPath)
-                        : htmlContent
+                    ? ListeningMarkupComponent_observing.decorate(htmlContent, observing, webAppContextPath)
+                    : htmlContent
 
                 );
     }
 
-
 }
diff --git a/valuetypes/sse/ui/wicket/src/main/java/org/apache/isis/valuetypes/sse/ui/wkt/markup/ListeningMarkupPanelFactoriesForWicket.java b/valuetypes/sse/ui/wicket/src/main/java/org/apache/isis/valuetypes/sse/ui/wkt/markup/ListeningMarkupPanelFactoriesForWicket.java
index 0e1af26..c439d9d 100644
--- a/valuetypes/sse/ui/wicket/src/main/java/org/apache/isis/valuetypes/sse/ui/wkt/markup/ListeningMarkupPanelFactoriesForWicket.java
+++ b/valuetypes/sse/ui/wicket/src/main/java/org/apache/isis/valuetypes/sse/ui/wkt/markup/ListeningMarkupPanelFactoriesForWicket.java
@@ -24,7 +24,8 @@ import org.apache.isis.applib.value.LocalResourcePath;
 import org.apache.isis.applib.value.Markup;
 import org.apache.isis.valuetypes.sse.metamodel.facets.SseObserveFacet;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
-import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponentFactory;
+import org.apache.isis.viewer.wicket.model.models.ValueModel;
+import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponent;
 import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupPanelFactories;
 
 import lombok.val;
@@ -49,26 +50,22 @@ public class ListeningMarkupPanelFactoriesForWicket {
 
 
         @Override
-        protected MarkupComponentFactory getMarkupComponentFactory() {
-            return (id, model) -> {
-                val markupComponent = new ListeningMarkupComponent(
-                        id, model, getEventStreamResource((ScalarModel)model));
-                markupComponent.setEnabled(false);
-                getCommonContext().getServiceInjector().injectServicesInto(markupComponent);
-                return markupComponent;
-            };
+        protected MarkupComponent newMarkupComponent(final String id, final ScalarModel model) {
+            val markupComponent = new ListeningMarkupComponent(
+                    id, model, getEventStreamResource(model));
+            markupComponent.setEnabled(false);
+            return getCommonContext().getServiceInjector().injectServicesInto(markupComponent);
         }
 
         // -- HELPER
 
-        private LocalResourcePath getEventStreamResource(ScalarModel scalarModel) {
+        private LocalResourcePath getEventStreamResource(final ScalarModel scalarModel) {
             val observeFacet  = scalarModel.getFacet(SseObserveFacet.class);
             return observeFacet!=null
                     ? observeFacet.getEventStreamResource()
-                            : null;
+                    : null;
         }
 
-
     }
 
     // -- STANDALONE
@@ -82,12 +79,10 @@ public class ListeningMarkupPanelFactoriesForWicket {
         }
 
         @Override
-        protected MarkupComponentFactory getMarkupComponentFactory() {
-            return (id, model) -> {
-                val markupComponent = new ListeningMarkupComponent(id, model, /*observing*/ null);
-                getCommonContext().getServiceInjector().injectServicesInto(markupComponent);
-                return markupComponent;
-            };
+        protected MarkupComponent newMarkupComponent(final String id, final ValueModel model) {
+            return getCommonContext()
+                    .getServiceInjector()
+                    .injectServicesInto(new ListeningMarkupComponent(id, model));
         }
 
     }
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ValueModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ValueModel.java
index 3fba953..409ded0 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ValueModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ValueModel.java
@@ -30,7 +30,8 @@ import lombok.NonNull;
 /**
  * Represents a standalone value (used for standalone value page).
  */
-public class ValueModel extends ModelAbstract<ManagedObject> {
+public class ValueModel
+extends ModelAbstract<ManagedObject> {
 
     private static final long serialVersionUID = 1L;
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponent.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponent.java
index cc6d9d9..b7069f8 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponent.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponent.java
@@ -29,6 +29,7 @@ import org.apache.wicket.model.IModel;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
 import org.apache.isis.viewer.common.model.feature.ParameterUiModel;
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.model.models.ScalarPropertyModel;
 import org.apache.isis.viewer.wicket.model.models.ValueModel;
 
@@ -38,7 +39,15 @@ public class MarkupComponent extends WebComponent {
 
     private static final long serialVersionUID = 1L;
 
-    public MarkupComponent(final String id, final IModel<?> model){
+    public MarkupComponent(final String id, final ScalarModel model){
+        super(id, model);
+    }
+
+    public MarkupComponent(final String id, final ValueModel model){
+        super(id, model);
+    }
+
+    public MarkupComponent(final String id, final IModel<String> model){
         super(id, model);
     }
 
@@ -71,7 +80,7 @@ public class MarkupComponent extends WebComponent {
             }
 
             val asHtml = lookupObjectFeatureIn(getDefaultModel())
-            .map(feature->adapter.titleString(conf->conf.feature(feature)))
+            .map(feature->adapter.htmlString(feature))
             .orElseGet(adapter::titleString);
 
             if(asHtml != null) {
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponentFactory.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponentFactory.java
index 47ac44d..47ff845 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponentFactory.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponentFactory.java
@@ -21,8 +21,8 @@ package org.apache.isis.viewer.wicket.ui.components.scalars.markup;
 import org.apache.wicket.model.IModel;
 
 @FunctionalInterface
-public interface MarkupComponentFactory {
+public interface MarkupComponentFactory<T extends IModel<?>> {
 
-    MarkupComponent newMarkupComponent(String id, IModel<?> model);
+    MarkupComponent newMarkupComponent(String id, T model);
 
 }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanelFactories.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanelFactories.java
index 140d70d..d342b31 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanelFactories.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanelFactories.java
@@ -73,10 +73,10 @@ public class MarkupPanelFactories {
 
         @Override
         public final Component createComponent(final String id, final IModel<?> model) {
-            return new ParentedMarkupPanel(id, (ScalarModel) model, getMarkupComponentFactory());
+            return new ParentedMarkupPanel(id, (ScalarModel) model, this::newMarkupComponent);
         }
 
-        protected abstract MarkupComponentFactory getMarkupComponentFactory();
+        protected abstract MarkupComponent newMarkupComponent(String id, ScalarModel model);
 
     }
 
@@ -109,10 +109,10 @@ public class MarkupPanelFactories {
 
         @Override
         public final Component createComponent(final String id, final IModel<?> model) {
-            return new StandaloneMarkupPanel(id, (ValueModel) model, getMarkupComponentFactory());
+            return new StandaloneMarkupPanel(id, (ValueModel) model, this::newMarkupComponent);
         }
 
-        protected abstract MarkupComponentFactory getMarkupComponentFactory();
+        protected abstract MarkupComponent newMarkupComponent(String id, ValueModel model);
     }
 
     // -- CONCRETE COMPONENT FACTORY - PARENTED
@@ -125,12 +125,10 @@ public class MarkupPanelFactories {
         }
 
         @Override
-        protected MarkupComponentFactory getMarkupComponentFactory() {
-            return (id, model) -> {
-                val markupComponent = new MarkupComponent(id, model);
-                markupComponent.setEnabled(false);
-                return markupComponent;
-            };
+        protected MarkupComponent newMarkupComponent(final String id, final ScalarModel model) {
+            val markupComponent = new MarkupComponent(id, model);
+            markupComponent.setEnabled(false);
+            return markupComponent;
         }
 
     }
@@ -145,8 +143,8 @@ public class MarkupPanelFactories {
         }
 
         @Override
-        protected MarkupComponentFactory getMarkupComponentFactory() {
-            return MarkupComponent::new;
+        protected MarkupComponent newMarkupComponent(final String id, final ValueModel model) {
+            return new MarkupComponent(id, model);
         }
     }
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/ParentedMarkupPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/ParentedMarkupPanel.java
index f3d5295..7b68cac 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/ParentedMarkupPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/ParentedMarkupPanel.java
@@ -34,12 +34,12 @@ import org.apache.isis.viewer.wicket.ui.util.Tooltips;
 public class ParentedMarkupPanel extends MultiLineStringPanel {
 
     private static final long serialVersionUID = 1L;
-    private final transient MarkupComponentFactory markupComponentFactory;
+    private final transient MarkupComponentFactory<ScalarModel> markupComponentFactory;
 
     public ParentedMarkupPanel(
             final String id,
             final ScalarModel scalarModel,
-            final MarkupComponentFactory markupComponentFactory) {
+            final MarkupComponentFactory<ScalarModel> markupComponentFactory) {
 
         super(id, scalarModel);
         this.markupComponentFactory = markupComponentFactory;
@@ -78,7 +78,7 @@ public class ParentedMarkupPanel extends MultiLineStringPanel {
         return createMarkupComponent(ID_SCALAR_IF_COMPACT);
     }
 
-    protected MarkupComponent createMarkupComponent(final String id) {
+    protected final MarkupComponent createMarkupComponent(final String id) {
         return markupComponentFactory.newMarkupComponent(id, getModel());
     }
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/StandaloneMarkupPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/StandaloneMarkupPanel.java
index b80b1c5..4a25a26 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/StandaloneMarkupPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/StandaloneMarkupPanel.java
@@ -31,9 +31,9 @@ extends PanelAbstract<ManagedObject, ValueModel> {
     private static final String ID_STANDALONE_VALUE = "standaloneValue";
 
     public StandaloneMarkupPanel(
-            String id,
-            ValueModel valueModel,
-            MarkupComponentFactory markupComponentFactory) {
+            final String id,
+            final ValueModel valueModel,
+            final MarkupComponentFactory<ValueModel> markupComponentFactory) {
 
         super(id, valueModel);
         val markupComponent = markupComponentFactory
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/TreePanelFactories.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/TreePanelFactories.java
index 5832b28..7068146 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/TreePanelFactories.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/TreePanelFactories.java
@@ -26,12 +26,11 @@ import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.model.models.ValueModel;
 import org.apache.isis.viewer.wicket.ui.ComponentFactory;
 import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
-import org.apache.isis.viewer.wicket.ui.components.scalars.markup.ParentedMarkupPanel;
 
 import lombok.val;
 
 /**
- * {@link ComponentFactory} for {@link ParentedMarkupPanel}.
+ * {@link ComponentFactory} for {@link ParentedTreePanel}.
  */
 public class TreePanelFactories {