From 389b0d072ce6eb651e210b714b84861e238e37a2 Mon Sep 17 00:00:00 2001
From: JesseBrault0709 <62299747+JesseBrault0709@users.noreply.github.com>
Date: Thu, 13 Jun 2024 21:55:03 +0200
Subject: [PATCH] Outlet and Render components.
---
TODO.md | 9 +++-
.../web/DefaultWebViewComponentScope.groovy | 2 +
.../view/component/web/lib/Outlet.groovy | 22 +++++++++
.../view/component/web/lib/Render.groovy | 28 +++++++++++
.../view/component/web/lib/OutletTests.groovy | 17 +++++++
.../view/component/web/lib/RenderTests.groovy | 47 +++++++++++++++++++
6 files changed, 123 insertions(+), 2 deletions(-)
create mode 100644 web-view-components/src/main/groovy/groowt/view/component/web/lib/Outlet.groovy
create mode 100644 web-view-components/src/main/groovy/groowt/view/component/web/lib/Render.groovy
create mode 100644 web-view-components/src/test/groovy/groowt/view/component/web/lib/OutletTests.groovy
create mode 100644 web-view-components/src/test/groovy/groowt/view/component/web/lib/RenderTests.groovy
diff --git a/TODO.md b/TODO.md
index 26c412a..768e37a 100644
--- a/TODO.md
+++ b/TODO.md
@@ -22,12 +22,17 @@ For example:
- fp
- [ ] Remove gradle plugins and whatnot until we actually build the whole framework
-## 0.1.2
+## 0.1.3
+- [ ] refactor tools/gradle start scripts to use dist instead of custom bin script
+ - [ ] have custom bin/* scripts which point to dist(s) for convenience
- [ ] di bug: @Singleton toSelf() causes stack overflow
-- [ ] `Outlet` component for rendering children like so:
+
+## 0.1.2
+- [x] `Outlet` component for rendering children like so:
```
```
+- [x] `Render` component
- [x] `data-` attributes need to function correctly (really any attribute with hyphen).
## 0.1.1
diff --git a/web-view-components/src/main/groovy/groowt/view/component/web/DefaultWebViewComponentScope.groovy b/web-view-components/src/main/groovy/groowt/view/component/web/DefaultWebViewComponentScope.groovy
index 030cabe..db4cdd1 100644
--- a/web-view-components/src/main/groovy/groowt/view/component/web/DefaultWebViewComponentScope.groovy
+++ b/web-view-components/src/main/groovy/groowt/view/component/web/DefaultWebViewComponentScope.groovy
@@ -14,6 +14,8 @@ class DefaultWebViewComponentScope extends DefaultComponentScope implements WebV
addWithAttr(DefaultCase)
addWithAttr(Each)
addWithAttr(Echo)
+ addWithAttr(Outlet)
+ addWithAttr(Render)
addWithAttr(Switch)
addWithAttr(WhenNotEmpty)
addWithAttr(WhenNotNull)
diff --git a/web-view-components/src/main/groovy/groowt/view/component/web/lib/Outlet.groovy b/web-view-components/src/main/groovy/groowt/view/component/web/lib/Outlet.groovy
new file mode 100644
index 0000000..6108771
--- /dev/null
+++ b/web-view-components/src/main/groovy/groowt/view/component/web/lib/Outlet.groovy
@@ -0,0 +1,22 @@
+package groowt.view.component.web.lib
+
+import groowt.view.View
+import groowt.view.component.runtime.DefaultComponentWriter
+
+class Outlet extends DelegatingWebViewComponent {
+
+ private final List givenChildren
+
+ Outlet(Map attr) {
+ givenChildren = attr.children ?: []
+ }
+
+ @Override
+ protected View getDelegate() {
+ return { Writer w ->
+ def cw = new DefaultComponentWriter(w, context.renderContext, context)
+ givenChildren.each { cw << it }
+ }
+ }
+
+}
diff --git a/web-view-components/src/main/groovy/groowt/view/component/web/lib/Render.groovy b/web-view-components/src/main/groovy/groowt/view/component/web/lib/Render.groovy
new file mode 100644
index 0000000..a4072c2
--- /dev/null
+++ b/web-view-components/src/main/groovy/groowt/view/component/web/lib/Render.groovy
@@ -0,0 +1,28 @@
+package groowt.view.component.web.lib
+
+import groowt.view.View
+
+class Render extends DelegatingWebViewComponent {
+
+ private final Object item
+
+ Render(Map attr) {
+ item = Objects.requireNonNull(attr.item, " attribute 'item' must not be null.")
+ }
+
+ @Override
+ protected View getDelegate() {
+ return { Writer w ->
+ if (item.respondsTo('renderTo', [Writer] as Class[])) {
+ item.renderTo(w)
+ } else if (item.respondsTo('render')) {
+ w << item.render()
+ } else {
+ throw new IllegalArgumentException(
+ ' must use an item which responds to either renderTo(Writer) or render().'
+ )
+ }
+ }
+ }
+
+}
diff --git a/web-view-components/src/test/groovy/groowt/view/component/web/lib/OutletTests.groovy b/web-view-components/src/test/groovy/groowt/view/component/web/lib/OutletTests.groovy
new file mode 100644
index 0000000..6503d91
--- /dev/null
+++ b/web-view-components/src/test/groovy/groowt/view/component/web/lib/OutletTests.groovy
@@ -0,0 +1,17 @@
+package groowt.view.component.web.lib
+
+import org.junit.jupiter.api.Test
+
+class OutletTests extends AbstractWebViewComponentTests {
+
+ @Test
+ void smokeScreen() {
+ doTest('', '')
+ }
+
+ @Test
+ void withChildren() {
+ doTest('', '012')
+ }
+
+}
diff --git a/web-view-components/src/test/groovy/groowt/view/component/web/lib/RenderTests.groovy b/web-view-components/src/test/groovy/groowt/view/component/web/lib/RenderTests.groovy
new file mode 100644
index 0000000..7e18147
--- /dev/null
+++ b/web-view-components/src/test/groovy/groowt/view/component/web/lib/RenderTests.groovy
@@ -0,0 +1,47 @@
+package groowt.view.component.web.lib
+
+import org.junit.jupiter.api.Test
+
+class RenderTests extends AbstractWebViewComponentTests {
+
+ static final class RenderToExample {
+
+ void renderTo(Writer w) {
+ w << 'Hello, World!'
+ }
+
+ }
+
+ static final class RenderExample {
+
+ String render() {
+ 'Hello, World!'
+ }
+
+ }
+
+ @Test
+ void renderToExample() {
+ doTest('''
+ ---
+ package groowt.view.component.web.lib
+ ---
+
+ '''.stripIndent().trim(),
+ 'Hello, World!'
+ )
+ }
+
+ @Test
+ void renderExample() {
+ doTest('''
+ ---
+ package groowt.view.component.web.lib
+ ---
+
+ '''.stripIndent().trim(),
+ 'Hello, World!'
+ )
+ }
+
+}