Working on IntrinsicHtml and nested render closures.
This commit is contained in:
parent
6ee903bde0
commit
5b1a1bcdec
4
web-views/sketching/echoElement.wvc
Normal file
4
web-views/sketching/echoElement.wvc
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
import groowt.view.web.lib.Echo
|
||||||
|
---
|
||||||
|
<Echo greeting="Hello!"><p>${context}</p></Echo>
|
@ -56,24 +56,23 @@ class IntrinsicHtml extends DelegatingWebViewComponent implements WithHtml {
|
|||||||
if (this.isVoidElement && this.hasChildren()) {
|
if (this.isVoidElement && this.hasChildren()) {
|
||||||
throw new ComponentRenderException('A void html element cannot have children.')
|
throw new ComponentRenderException('A void html element cannot have children.')
|
||||||
}
|
}
|
||||||
return {
|
return { writer ->
|
||||||
it << '<'
|
writer << '<'
|
||||||
it << this.name
|
writer << this.name
|
||||||
if (!this.attr.isEmpty()) {
|
if (!this.attr.isEmpty()) {
|
||||||
it << ' '
|
writer << ' '
|
||||||
this.formatAttr(it)
|
this.formatAttr(writer)
|
||||||
}
|
}
|
||||||
it << '>'
|
writer << '>'
|
||||||
if (this.hasChildren()) {
|
if (this.hasChildren()) {
|
||||||
this.children.each {
|
this.children.each {
|
||||||
def renderer = it.getRenderer(this)
|
it.renderTo(writer, this)
|
||||||
renderer.call(it.child)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!this.isVoidElement) {
|
if (!this.isVoidElement) {
|
||||||
it << '</'
|
writer << '</'
|
||||||
it << this.name
|
writer << this.name
|
||||||
it << '>'
|
writer << '>'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,21 +4,28 @@ import groovy.lang.Closure;
|
|||||||
import groowt.view.component.ComponentTemplate;
|
import groowt.view.component.ComponentTemplate;
|
||||||
import groowt.view.component.ViewComponent;
|
import groowt.view.component.ViewComponent;
|
||||||
import groowt.view.component.runtime.ComponentWriter;
|
import groowt.view.component.runtime.ComponentWriter;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import groowt.view.component.runtime.DefaultComponentWriter;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.io.Writer;
|
||||||
|
|
||||||
public class WebViewComponentChild {
|
public class WebViewComponentChild {
|
||||||
|
|
||||||
private static final class ChildRenderClosure extends Closure<Void> {
|
private static final class ChildRenderClosure extends Closure<Void> {
|
||||||
|
|
||||||
private final ViewComponent parent;
|
private final ViewComponent parent;
|
||||||
private final @Nullable Object child;
|
private final Object child;
|
||||||
|
private final ComponentWriter writer;
|
||||||
|
|
||||||
public ChildRenderClosure(ComponentTemplate template, ViewComponent parent, @Nullable Object child) {
|
public ChildRenderClosure(
|
||||||
|
ComponentTemplate template,
|
||||||
|
ViewComponent parent,
|
||||||
|
ComponentWriter writer,
|
||||||
|
Object child
|
||||||
|
) {
|
||||||
super(template, template);
|
super(template, template);
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.child = child;
|
this.child = child;
|
||||||
|
this.writer = writer;
|
||||||
this.setDelegate(this.parent);
|
this.setDelegate(this.parent);
|
||||||
this.setResolveStrategy(Closure.DELEGATE_FIRST);
|
this.setResolveStrategy(Closure.DELEGATE_FIRST);
|
||||||
}
|
}
|
||||||
@ -27,23 +34,19 @@ public class WebViewComponentChild {
|
|||||||
return this.parent;
|
return this.parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doCall(ComponentWriter writer) {
|
public void doCall() {
|
||||||
writer.append(Objects.requireNonNull(this.child));
|
this.writer.append(this.child);
|
||||||
}
|
|
||||||
|
|
||||||
public void doCall(ComponentWriter writer, Object givenChild) {
|
|
||||||
writer.append(givenChild);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ComponentTemplate template;
|
private final ComponentTemplate template;
|
||||||
private final ComponentWriter out;
|
private final ComponentWriter componentWriter;
|
||||||
private final Object child;
|
private final Object child;
|
||||||
|
|
||||||
public WebViewComponentChild(ComponentTemplate template, ComponentWriter out, Object child) {
|
public WebViewComponentChild(ComponentTemplate template, ComponentWriter componentWriter, Object child) {
|
||||||
this.template = template;
|
this.template = template;
|
||||||
this.out = out;
|
this.componentWriter = componentWriter;
|
||||||
this.child = child;
|
this.child = child;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,13 +55,14 @@ public class WebViewComponentChild {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void render(ViewComponent parent) {
|
public void render(ViewComponent parent) {
|
||||||
final var cl = this.getRenderer(parent);
|
new ChildRenderClosure(this.template, parent, this.componentWriter, this.child).call();
|
||||||
cl.call(this.child);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Closure<Void> getRenderer(ViewComponent parent) {
|
public Writer renderTo(Writer out, ViewComponent parent) {
|
||||||
final var cl = new ChildRenderClosure(this.template, parent, null);
|
final var componentWriter = new DefaultComponentWriter(out);
|
||||||
return cl.curry(this.out);
|
final var childRenderClosure = new ChildRenderClosure(this.template, parent, componentWriter, this.child);
|
||||||
|
childRenderClosure.call();
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package groowt.view.web.transpile.resolve;
|
package groowt.view.web.transpile.resolve;
|
||||||
|
|
||||||
import groowt.view.web.WebViewComponentBugError;
|
|
||||||
import groowt.view.web.compiler.WebViewComponentTemplateCompileUnit;
|
import groowt.view.web.compiler.WebViewComponentTemplateCompileUnit;
|
||||||
import groowt.view.web.util.Either;
|
import groowt.view.web.util.Either;
|
||||||
import org.codehaus.groovy.ast.ClassNode;
|
import org.codehaus.groovy.ast.ClassNode;
|
||||||
@ -30,10 +29,12 @@ public class ModuleNodeComponentClassNodeResolver extends CachingComponentClassN
|
|||||||
|
|
||||||
// try pre-pending package and asking for fqn
|
// try pre-pending package and asking for fqn
|
||||||
final var packageName = this.moduleNode.getPackageName();
|
final var packageName = this.moduleNode.getPackageName();
|
||||||
|
final String fqn;
|
||||||
if (packageName.endsWith(".")) {
|
if (packageName.endsWith(".")) {
|
||||||
throw new WebViewComponentBugError(new IllegalStateException("Package name illegally ends with '.'"));
|
fqn = this.moduleNode + nameWithoutPackage;
|
||||||
|
} else {
|
||||||
|
fqn = this.moduleNode.getPackageName() + "." + nameWithoutPackage;
|
||||||
}
|
}
|
||||||
final var fqn = this.moduleNode.getPackageName() + "." + nameWithoutPackage;
|
|
||||||
final var withPackage = this.getClassForFqn(fqn);
|
final var withPackage = this.getClassForFqn(fqn);
|
||||||
if (withPackage.isRight()) {
|
if (withPackage.isRight()) {
|
||||||
return withPackage;
|
return withPackage;
|
||||||
|
@ -22,8 +22,8 @@ class IntrinsicHtmlTests extends AbstractWebViewComponentTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Disabled('Until we figure out nested closure delegates')
|
@Disabled('Until we figure out nested closure delegates')
|
||||||
void canUseEchoAttrProperty() {
|
void canUseEchoAttrPropertyViaContext() {
|
||||||
this.doTest('<Echo greeting="Hello!"><p>$greeting</p></Echo>', '<p>Hello!</p>')
|
this.doTest('<Echo greeting="Hello!"><p>${context}</p></Echo>', '<p>Hello!</p>')
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user