Compare commits

..

No commits in common. "9495849dc9b2a5495d651bd1ced36f84435bd1ce" and "589bbca889ec0af0480351f962133c740431d160" have entirely different histories.

8 changed files with 7 additions and 68 deletions

View File

@ -34,8 +34,8 @@ For example:
- [x] wvcc bug: Nested static view classes are not seen by compiler - [x] wvcc bug: Nested static view classes are not seen by compiler
- This required tweaking how the configurations are passed around. Ultimately, we should strive for less complexity - This required tweaking how the configurations are passed around. Ultimately, we should strive for less complexity
in this regard. in this regard.
- [x] `OutletContainer` trait or interface for components which can contain an `<Outlet />` child. - [ ] `OutletContainer` trait or interface for components which can contain an `<Outlet />` child.
- [x] `Context` should have methods for simply finding an ancestor of a certain type without the need for a predicate. - [ ] `Context` should have methods for simply finding an ancestor of a certain type without the need for a predicate.
## 0.1.2 ## 0.1.2
- [x] `Outlet` component for rendering children like so: - [x] `Outlet` component for rendering children like so:

View File

@ -99,23 +99,6 @@ public interface ComponentContext {
return ancestorClass.cast(this.findNearestAncestor(matching.and(ancestorClass::isInstance))); return ancestorClass.cast(this.findNearestAncestor(matching.and(ancestorClass::isInstance)));
} }
default <T extends ViewComponent> @Nullable T findNearestAncestor(Class<T> ancestorClass) {
return ancestorClass.cast(this.findNearestAncestor(ancestorClass::isInstance));
}
boolean hasAncestor(Predicate<? super ViewComponent> matching);
default <T extends ViewComponent> boolean hasAncestor(
Class<T> ancestorClass,
Predicate<? super ViewComponent> matching
) {
return this.hasAncestor(matching.and(ancestorClass::isInstance));
}
default <T extends ViewComponent> boolean hasAncestor(Class<T> ancestorClass) {
return this.hasAncestor(ancestorClass::isInstance);
}
List<ViewComponent> getAllAncestors(); List<ViewComponent> getAllAncestors();
} }

View File

@ -70,10 +70,7 @@ public class DefaultComponentContext implements ComponentContext {
public @Nullable ViewComponent findNearestAncestor(Predicate<? super ViewComponent> matching) { public @Nullable ViewComponent findNearestAncestor(Predicate<? super ViewComponent> matching) {
final List<ViewComponent> componentStack = this.getRenderContext().getComponentStack(); final List<ViewComponent> componentStack = this.getRenderContext().getComponentStack();
if (componentStack.size() > 1) { if (componentStack.size() > 1) {
// 1/27/25: earlier this was originally componentStack.size() - 1 as the second argument to sublist(). for (final var ancestor : componentStack.subList(1, componentStack.size() -1)) {
// On examination today, it didn't make sense, because it would be chopping off the farthest ancestor from
// search. So I removed it, in accordance with the implementation in hasAncestor().
for (final var ancestor : componentStack.subList(1, componentStack.size())) {
if (matching.test(ancestor)) { if (matching.test(ancestor)) {
return ancestor; return ancestor;
} }
@ -82,19 +79,6 @@ public class DefaultComponentContext implements ComponentContext {
return null; return null;
} }
@Override
public boolean hasAncestor(Predicate<? super ViewComponent> matching) {
final List<ViewComponent> componentStack = this.getRenderContext().getComponentStack();
if (componentStack.size() > 1) {
for (final var ancestor : componentStack.subList(1, componentStack.size())) {
if (matching.test(ancestor)) {
return true;
}
}
}
return false;
}
@Override @Override
public List<ViewComponent> getAllAncestors() { public List<ViewComponent> getAllAncestors() {
final List<ViewComponent> componentStack = this.getRenderContext().getComponentStack(); final List<ViewComponent> componentStack = this.getRenderContext().getComponentStack();

View File

@ -1,4 +1,4 @@
package groowt.view.component.web.lib package groowt.view.component.web
trait WithHtml { trait WithHtml {

View File

@ -5,6 +5,7 @@ import groowt.view.component.ComponentRenderException
import groowt.view.component.context.ComponentContext import groowt.view.component.context.ComponentContext
import groowt.view.component.context.ComponentScope.TypeAndFactory import groowt.view.component.context.ComponentScope.TypeAndFactory
import groowt.view.component.factory.ComponentFactory import groowt.view.component.factory.ComponentFactory
import groowt.view.component.web.WithHtml
class IntrinsicHtml extends DelegatingWebViewComponent implements WithHtml { class IntrinsicHtml extends DelegatingWebViewComponent implements WithHtml {

View File

@ -1,7 +1,6 @@
package groowt.view.component.web.lib package groowt.view.component.web.lib
import groowt.view.View import groowt.view.View
import groowt.view.component.ComponentRenderException
import groowt.view.component.runtime.DefaultComponentWriter import groowt.view.component.runtime.DefaultComponentWriter
class Outlet extends DelegatingWebViewComponent { class Outlet extends DelegatingWebViewComponent {
@ -15,11 +14,6 @@ class Outlet extends DelegatingWebViewComponent {
@Override @Override
protected View getDelegate() { protected View getDelegate() {
return { Writer w -> return { Writer w ->
if (!context.hasAncestor(OutletContainer)) {
throw new ComponentRenderException(
"<Outlet> is being used outside of a component implementing OutletContainer."
)
}
def cw = new DefaultComponentWriter(w, context.renderContext, context) def cw = new DefaultComponentWriter(w, context.renderContext, context)
givenChildren.each { cw << it } givenChildren.each { cw << it }
} }

View File

@ -1,5 +0,0 @@
package groowt.view.component.web.lib
import groowt.view.component.web.WebViewComponent
interface OutletContainer extends WebViewComponent {}

View File

@ -1,35 +1,17 @@
package groowt.view.component.web.lib package groowt.view.component.web.lib
import groowt.view.component.web.WebViewComponentContext
import groowt.view.component.web.WebViewComponentScope
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
class OutletTests extends AbstractWebViewComponentTests { class OutletTests extends AbstractWebViewComponentTests {
static final class DummyOutletContainer extends Echo implements OutletContainer {
DummyOutletContainer() {
super([:])
}
}
@Override
void configureContext(WebViewComponentContext context) {
context.configureRootScope(WebViewComponentScope) {
addWithNoArgConstructor(DummyOutletContainer)
}
}
@Test @Test
void smokeScreen() { void smokeScreen() {
doTest('<OutletTests.DummyOutletContainer><Outlet /></OutletTests.DummyOutletContainer>', '') doTest('<Outlet />', '')
} }
@Test @Test
void withChildren() { void withChildren() {
doTest('<OutletTests.DummyOutletContainer><Echo items={[0, 1, 2]}><Outlet children={items} /></Echo></OutletTests.DummyOutletContainer>', '012') doTest('<Echo items={[0, 1, 2]}><Outlet children={items} /></Echo>', '012')
} }
} }