Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XRENDERING-563: Handle metadata rendering in HTML macro #175

Merged
merged 5 commits into from
May 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,16 @@ public ChainingListener getNextListener(Class<? extends ChainingListener> listen
*/
public ChainingListener getListener(Class<? extends ChainingListener> listenerClass)
{
return this.listeners.get(listenerClass).peek();
Deque<ChainingListener> result = this.listeners.get(listenerClass);
if (result == null) {
for (Class<? extends ChainingListener> listenerKey : this.listeners.keySet()) {
if (listenerClass.isAssignableFrom(listenerKey)) {
result = this.listeners.get(listenerKey);
break;
}
}
}
return result.peek();
}

/**
Expand Down
15 changes: 15 additions & 0 deletions xwiki-rendering-macros/xwiki-rendering-macro-html/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,21 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.xwiki.rendering</groupId>
<artifactId>xwiki-rendering-syntax-annotatedxhtml</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.xwiki.rendering</groupId>
<artifactId>xwiki-rendering-syntax-html5</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.xwiki.rendering</groupId>
<artifactId>xwiki-rendering-syntax-annotatedhtml5</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.rendering.internal.macro.html;

import org.xwiki.component.phase.Initializable;
import org.xwiki.component.phase.InitializationException;
import org.xwiki.rendering.listener.chaining.EmptyBlockChainingListener;
import org.xwiki.rendering.listener.chaining.ListenerChain;
import org.xwiki.rendering.listener.chaining.MetaDataStateChainingListener;
import org.xwiki.rendering.renderer.AbstractChainingPrintRenderer;
import org.xwiki.stability.Unstable;

/**
* Define a generic HTMLMacroRenderer with the right {@link ListenerChain}.
*
* @version $Id$
* @since 11.4RC1
*/
@Unstable
public abstract class AbstractHTMLMacroRenderer extends AbstractChainingPrintRenderer implements Initializable
{
/**
* @return the specific syntax {@link AbstractChainingPrintRenderer} that is required for the concrete HTMLMacro
* renderer.
*/
protected abstract AbstractChainingPrintRenderer getSyntaxRenderer();

/**
* {@inheritDoc}
*
* @since 2.0M3
*/
@Override
public void initialize() throws InitializationException
{
ListenerChain chain = new ListenerChain();
setListenerChain(chain);

// Construct the listener chain in the right order. Listeners early in the chain are called before listeners
// placed later in the chain.
chain.addListener(this);
chain.addListener(new HTMLMacroBlockStateChainingListener(chain));
chain.addListener(new EmptyBlockChainingListener(chain));
chain.addListener(new MetaDataStateChainingListener(chain));
chain.addListener(new HTMLMacroChainingRenderer(getSyntaxRenderer()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xwiki.component.annotation.Component;
import org.xwiki.component.manager.ComponentLookupException;
import org.xwiki.component.manager.ComponentManager;
import org.xwiki.rendering.block.Block;
import org.xwiki.rendering.block.Block.Axes;
import org.xwiki.rendering.block.MacroBlock;
Expand Down Expand Up @@ -102,13 +104,12 @@ public class HTMLMacro extends AbstractMacro<HTMLMacroParameters>
private HTMLCleaner htmlCleaner;

/**
* Factory to create special XHTML renderer for the HTML Macro. We override the default XHTML renderer since we want
* special behaviors, for example to not escape special symbols (since we don't want to escape HTML tags for
* example).
* Default Factory to create special XHTML renderer for the HTML Macro.
* It is used as fallback in {@link #getRendererFactory(Syntax)}.
*/
@Inject
@Named("xhtmlmacro/1.0")
private PrintRendererFactory xhtmlRendererFactory;
private PrintRendererFactory defaultXHTMLRendererFactory;

/**
* The parser used to parse macro content.
Expand All @@ -122,6 +123,9 @@ public class HTMLMacro extends AbstractMacro<HTMLMacroParameters>
@Inject
private RenderingContext renderingContext;

@Inject
private ComponentManager componentManager;

/**
* Create and initialize the descriptor of the macro.
*/
Expand Down Expand Up @@ -280,7 +284,7 @@ private String renderWikiSyntax(String content, Transformation transformation, M

// Render the whole parsed content as a XHTML string
WikiPrinter printer = new DefaultWikiPrinter();
PrintRenderer renderer = this.xhtmlRendererFactory.createRenderer(printer);
PrintRenderer renderer = this.getRendererFactory(this.renderingContext.getTargetSyntax()).createRenderer(printer);
for (Block block : htmlMacroMarker.getChildren()) {
block.traverse(renderer);
}
Expand All @@ -294,6 +298,26 @@ private String renderWikiSyntax(String content, Transformation transformation, M
return xhtml;
}

/**
* Retrieve the renderer factory based on the given target syntax.
* In practice it's always a {@link HTMLMacroXHTMLRendererFactory} which is returned but the hint is used to build
* the right renderer in the factory.
*
* @param targetSyntax the syntax for which we want a {@link PrintRenderer}.
* @return a {@link HTMLMacroXHTMLRendererFactory} with the hint to build the right {@link PrintRenderer}.
* It fallbacks on {@link #defaultXHTMLRendererFactory} in case of ComponentLookupException.
* @since 11.4RC1
*/
private PrintRendererFactory getRendererFactory(Syntax targetSyntax)
{
String hint = HTMLMacroXHTMLRendererFactory.PREFIX_SYNTAX + targetSyntax.toIdString();
try {
return this.componentManager.getInstance(PrintRendererFactory.class, hint);
} catch (ComponentLookupException e) {
return this.defaultXHTMLRendererFactory;
}
}

/**
* @param context the macro transformation context
* @return the appropriate cleaner configuration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,32 @@

import java.util.Map;

import org.xwiki.rendering.internal.renderer.xhtml.XHTMLChainingRenderer;
import org.xwiki.rendering.internal.renderer.xhtml.image.XHTMLImageRenderer;
import org.xwiki.rendering.internal.renderer.xhtml.link.XHTMLLinkRenderer;
import org.xwiki.rendering.listener.WrappingListener;
import org.xwiki.rendering.listener.chaining.BlockStateChainingListener;
import org.xwiki.rendering.listener.chaining.ChainingListener;
import org.xwiki.rendering.listener.chaining.ListenerChain;
import org.xwiki.rendering.renderer.AbstractChainingPrintRenderer;
import org.xwiki.rendering.renderer.PrintRenderer;
import org.xwiki.rendering.renderer.printer.WikiPrinter;

/**
* Renderer that generates XHTML from a XDOM resulting from the parsing of text containing HTML mixed with wiki syntax.
* We override the default XHTML renderer since we want special behaviors, for example to not escape special symbols
* (since we don't want to escape HTML tags for example).
* Define some custom behaviours for the different HTMLMacro renderers: this wrapper takes as parameter the right syntax
* renderer and delegate to it most behaviours. Only some of them are rewritten.
*
* @version $Id $
* @since 1.8.3
* @version $Id$
* @since 11.4RC1
*/
public class HTMLMacroXHTMLChainingRenderer extends XHTMLChainingRenderer
public class HTMLMacroChainingRenderer extends WrappingListener implements ChainingListener, PrintRenderer
{
private AbstractChainingPrintRenderer printRenderer;

/**
* @param linkRenderer the object to render link events into XHTML. This is done so that it's pluggable because link
* rendering depends on how the underlying system wants to handle it. For example for XWiki we check if
* the document exists, we get the document URL, etc.
* @param imageRenderer the object to render image events into XHTML. This is done so that it's pluggable because
* image rendering depends on how the underlying system wants to handle it. For example for XWiki we
* check if the image exists as a document attachments, we get its URL, etc.
* @param listenerChain the chain of listener filters used to compute various states
* @since 2.0M3
* @param printRenderer the right syntax renderer to be called.
*/
public HTMLMacroXHTMLChainingRenderer(XHTMLLinkRenderer linkRenderer, XHTMLImageRenderer imageRenderer,
ListenerChain listenerChain)
public HTMLMacroChainingRenderer(AbstractChainingPrintRenderer printRenderer)
{
super(linkRenderer, imageRenderer, listenerChain);
this.printRenderer = printRenderer;
this.setWrappedListener(printRenderer);
}

/**
Expand Down Expand Up @@ -152,6 +148,25 @@ public void endMacroMarker(String name, Map<String, String> parameters, String c

protected BlockStateChainingListener getBlockState()
{
return (BlockStateChainingListener) getListenerChain().getListener(HTMLMacroBlockStateChainingListener.class);
return (BlockStateChainingListener) getListenerChain()
.getListener(HTMLMacroBlockStateChainingListener.class);
}

@Override
public ListenerChain getListenerChain()
{
return this.printRenderer.getListenerChain();
}

@Override
public WikiPrinter getPrinter()
{
return this.printRenderer.getPrinter();
}

@Override
public void setPrinter(WikiPrinter printer)
{
this.printRenderer.setPrinter(printer);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,21 @@
import org.xwiki.component.annotation.Component;
import org.xwiki.component.annotation.InstantiationStrategy;
import org.xwiki.component.descriptor.ComponentInstantiationStrategy;
import org.xwiki.component.phase.Initializable;
import org.xwiki.component.phase.InitializationException;
import org.xwiki.rendering.internal.renderer.xhtml.XHTMLChainingRenderer;
import org.xwiki.rendering.internal.renderer.xhtml.image.XHTMLImageRenderer;
import org.xwiki.rendering.internal.renderer.xhtml.link.XHTMLLinkRenderer;
import org.xwiki.rendering.listener.chaining.EmptyBlockChainingListener;
import org.xwiki.rendering.listener.chaining.ListenerChain;
import org.xwiki.rendering.listener.chaining.MetaDataStateChainingListener;
import org.xwiki.rendering.renderer.AbstractChainingPrintRenderer;

/**
* Renderer that generates XHTML from a XDOM resulting from the parsing of text containing HTML mixed with wiki syntax.
* We override the default XHTML renderer since we want special behaviors, for example to not escape special symbols
* (since we don't want to escape HTML tags for example).
*
* @version $Id $
* @version $Id$
* @since 1.8.3
*/
@Component
@Named("xhtmlmacro/1.0")
@InstantiationStrategy(ComponentInstantiationStrategy.PER_LOOKUP)
public class HTMLMacroXHTMLRenderer extends AbstractChainingPrintRenderer implements Initializable
public class HTMLMacroXHTMLRenderer extends AbstractHTMLMacroRenderer
{
/**
* To render link events into XHTML. This is done so that it's pluggable because link rendering depends on how the
Expand All @@ -63,23 +57,9 @@ public class HTMLMacroXHTMLRenderer extends AbstractChainingPrintRenderer implem
@Inject
private XHTMLImageRenderer imageRenderer;

/**
* {@inheritDoc}
*
* @since 2.0M3
*/
@Override
public void initialize() throws InitializationException
protected AbstractChainingPrintRenderer getSyntaxRenderer()
{
ListenerChain chain = new ListenerChain();
setListenerChain(chain);

// Construct the listener chain in the right order. Listeners early in the chain are called before listeners
// placed later in the chain.
chain.addListener(this);
chain.addListener(new HTMLMacroBlockStateChainingListener(chain));
chain.addListener(new EmptyBlockChainingListener(chain));
chain.addListener(new MetaDataStateChainingListener(chain));
chain.addListener(new HTMLMacroXHTMLChainingRenderer(this.linkRenderer, this.imageRenderer, chain));
return new XHTMLChainingRenderer(this.linkRenderer, this.imageRenderer, getListenerChain());
}
}
Loading