Skip to content

Commit 10ff127

Browse files
author
ageery
committed
Initial commit
0 parents  commit 10ff127

27 files changed

+1267
-0
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
build
2+
target
3+
out
4+
.gradle
5+
.idea

bianmen-core/build.gradle.kts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
kotlin {
2+
explicitApi()
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package dev.bombinating.bianmen
2+
3+
import dev.bombinating.bianmen.context.ComponentReferenceType
4+
import org.apache.wicket.Component
5+
import org.apache.wicket.behavior.Behavior
6+
import org.apache.wicket.model.IModel
7+
import org.wicketstuff.minis.behavior.EnabledModelBehavior
8+
import org.wicketstuff.minis.behavior.VisibleModelBehavior
9+
10+
/**
11+
* [Component]-related functionality
12+
*/
13+
public object ComponentExt {
14+
15+
/**
16+
* Configures a [Component] based on the parameters
17+
*
18+
* @receiver [Component] to configure
19+
* @return configured [Component]
20+
* @param T type of the [Component]
21+
* @param refType how the [Component] may be updated from the server
22+
* @param visibleWhen model of when the [Component] is visible
23+
* @param enabledWhen model of when the [Component] is enabled
24+
* @param renderBodyOnly whether to only render the body of the [Component]
25+
* @param escapeModelStrings whether to escape the [Component]'s model string
26+
* @param behaviors list of [Behavior]s to add to the [Component]
27+
*/
28+
@Suppress("LongParameterList")
29+
public fun <T: Component> T.config(
30+
refType: ComponentReferenceType? = null,
31+
visibleWhen: IModel<Boolean>? = null,
32+
enabledWhen: IModel<Boolean>? = null,
33+
renderBodyOnly: Boolean? = null,
34+
escapeModelStrings: Boolean? = null,
35+
behaviors: List<Behavior>? = null
36+
):T {
37+
refType?.config(this)
38+
visibleWhen?.let { add(VisibleModelBehavior(it)) }
39+
enabledWhen?.let { add(EnabledModelBehavior(it)) }
40+
renderBodyOnly?.let { this.renderBodyOnly = it }
41+
escapeModelStrings?.let { this.escapeModelStrings = it }
42+
@Suppress("SpreadOperator")
43+
behaviors?.let { add(*it.toTypedArray()) }
44+
return this
45+
}
46+
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package dev.bombinating.bianmen
2+
3+
import org.apache.wicket.model.IModel
4+
import org.apache.wicket.model.LoadableDetachableModel
5+
import org.apache.wicket.model.Model
6+
import java.io.Serializable
7+
8+
/**
9+
* [IModel]-related functionality
10+
*/
11+
public object ModelExt {
12+
13+
/**
14+
* Synonym for [IModel.getObject]/[IModel.setObject] that is not a Kotlin keyword
15+
*
16+
* @param T type of the model object
17+
*/
18+
public var <T> IModel<T>.obj: T
19+
get() = `object`
20+
set(value: T) {
21+
`object` = value
22+
}
23+
24+
/**
25+
* Returns a [LoadableDetachableModel] where the [lambda] generates the model object.
26+
*
27+
* @param T type of the model object
28+
* @param lambda lambda that provides the value for the [LoadableDetachableModel]
29+
* @return [LoadableDetachableModel] created from the [lambda]
30+
*/
31+
public inline fun <T> ldm(crossinline lambda: () -> T): IModel<T> = object : LoadableDetachableModel<T>() {
32+
override fun load(): T = lambda()
33+
}
34+
35+
/**
36+
* Returns an [IModel] where the object is the receiver.
37+
*
38+
* @param T type of the model object
39+
* @receiver value to use for the model object
40+
* @return model where the object is the receiver
41+
*/
42+
public fun <T: Serializable?> T.model(): IModel<T> = Model.of(this)
43+
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package dev.bombinating.bianmen.context
2+
3+
import org.apache.wicket.ajax.AjaxRequestTarget
4+
import org.apache.wicket.ajax.markup.html.AjaxLink
5+
6+
/**
7+
* Context for configuring an [AjaxLink].
8+
*
9+
* @param T type of [AjaxLink] to configure
10+
*/
11+
public interface AjaxLinkContext<T> : ComponentContext {
12+
/**
13+
* Sets a handler to be used for [AjaxLink.onClick]
14+
*
15+
* @param handler lambda to invoked in [AjaxLink.onClick]
16+
*/
17+
public fun onClick(handler: AjaxLink<T>.(target: AjaxRequestTarget) -> Unit)
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package dev.bombinating.bianmen.context
2+
3+
import org.apache.wicket.ajax.AjaxRequestTarget
4+
import org.apache.wicket.ajax.markup.html.AjaxLink
5+
6+
/**
7+
* Implementation of [AjaxLinkContext] that exposes the onClick lambda handler to use for an [AjaxLink].
8+
*
9+
* @param T type of [AjaxLink] to configure
10+
*/
11+
internal class AjaxLinkContextImpl<T> : ComponentContextImpl(), AjaxLinkContext<T> {
12+
/**
13+
* Mutable lambda to invoke in a [AjaxLink.onClick] method
14+
*/
15+
private var _onClick: (AjaxLink<T>.(target: AjaxRequestTarget) -> Unit)? = null
16+
17+
/**
18+
* Read-only lambda to invoke in a [AjaxLink.onClick] method
19+
*/
20+
internal val onClick: (AjaxLink<T>.(target: AjaxRequestTarget) -> Unit)?
21+
get() = _onClick
22+
23+
override fun onClick(handler: AjaxLink<T>.(target: AjaxRequestTarget) -> Unit) {
24+
_onClick = handler
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package dev.bombinating.bianmen.context
2+
3+
import org.apache.wicket.behavior.Behavior
4+
5+
/**
6+
* Context for configuring a Wicket [org.apache.wicket.Component].
7+
*/
8+
public interface ComponentContext {
9+
/**
10+
* [Behavior]s to add to a [org.apache.wicket.Component]
11+
* @param behaviors [Behavior]s to add to a [org.apache.wicket.Component]
12+
*/
13+
public fun add(vararg behaviors: Behavior)
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package dev.bombinating.bianmen.context
2+
3+
import org.apache.wicket.behavior.Behavior
4+
5+
/**
6+
* Implementation of [ComponentContext] that exposes the list of [Behavior]s to add to the [org.apache.wicket.Component]
7+
*/
8+
internal open class ComponentContextImpl : ComponentContext {
9+
/**
10+
* Private, mutable list of [Behavior]s to add to a [org.apache.wicket.Component]
11+
*/
12+
private val _behaviors: MutableList<Behavior> = mutableListOf()
13+
14+
/**
15+
* Read-only list of [Behavior]s to add to a [org.apache.wicket.Component]
16+
*/
17+
internal val behaviors: List<Behavior>
18+
get() = _behaviors
19+
20+
override fun add(vararg behaviors: Behavior) {
21+
_behaviors.addAll(behaviors)
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package dev.bombinating.bianmen.context
2+
3+
import org.apache.wicket.Component
4+
5+
/**
6+
* The ways in which a [Component] on the client can be reference from the server.
7+
*/
8+
public enum class ComponentReferenceType(
9+
private val outputMarkupId: Boolean,
10+
private val outputMarkupPlaceholderTag: Boolean
11+
) {
12+
/**
13+
* The [Component] cannot be updated on the client from the server.
14+
* This corresponds to setting both the [Component.setOutputMarkupId] and [Component.setOutputMarkupPlaceholderTag]
15+
* properties of a [Component] to false.
16+
*/
17+
None(outputMarkupId = false, outputMarkupPlaceholderTag = false),
18+
19+
/**
20+
* The [Component] can be updated on the client as long as it is visible.
21+
* This corresponds to setting the [Component.setOutputMarkupId] to true.
22+
*/
23+
Visible(outputMarkupId = true, outputMarkupPlaceholderTag = false),
24+
25+
/**
26+
* The [Component] can always be updated on the client, regardless of whether it is visible.
27+
* This corresponds to setting the [Component.setOutputMarkupPlaceholderTag] to true.
28+
*/
29+
Always(outputMarkupId = true, outputMarkupPlaceholderTag = true)
30+
;
31+
32+
/**
33+
* Sets the [Component.setOutputMarkupId] and [Component.setOutputMarkupPlaceholderTag] flags to the appropriate
34+
* values for the given [Component].
35+
*
36+
* @param component [Component] on which to set the [Component.setOutputMarkupId] and
37+
* [Component.setOutputMarkupPlaceholderTag] values, based on the enum
38+
*/
39+
public fun config(component: Component) {
40+
component.outputMarkupId = outputMarkupId
41+
component.outputMarkupPlaceholderTag = outputMarkupPlaceholderTag
42+
}
43+
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package dev.bombinating.bianmen.factory
2+
3+
import dev.bombinating.bianmen.ComponentExt.config
4+
import dev.bombinating.bianmen.context.AjaxLinkContext
5+
import dev.bombinating.bianmen.context.AjaxLinkContextImpl
6+
import dev.bombinating.bianmen.context.ComponentReferenceType
7+
import org.apache.wicket.ajax.AjaxRequestTarget
8+
import org.apache.wicket.ajax.markup.html.AjaxLink
9+
import org.apache.wicket.model.IModel
10+
11+
/**
12+
* Factory methods for creating [AjaxLink]s.
13+
*/
14+
public object AjaxLinkFactory {
15+
/**
16+
* Creates a new [AjaxLink] based on the parameters.
17+
*
18+
* @param T type of [AjaxLink] to create
19+
* @param id Wicket id of the [AjaxLink]
20+
* @param model the model for the [AjaxLink]
21+
* @param refType how the [AjaxLink] may be updated from the server
22+
* @param visibleWhen model of when the [AjaxLink] is visible
23+
* @param enabledWhen model of when the [AjaxLink] is enabled
24+
* @param renderBodyOnly whether to only render the body of the [AjaxLink]
25+
* @param escapeModelStrings whether to escape the [AjaxLink]'s model string
26+
* @param config lambda for configuring the [AjaxLink]
27+
*/
28+
@Suppress("LongParameterList")
29+
public fun <T> ajaxLink(
30+
id: String,
31+
model: IModel<T>?,
32+
refType: ComponentReferenceType? = null,
33+
visibleWhen: IModel<Boolean>? = null,
34+
enabledWhen: IModel<Boolean>? = null,
35+
renderBodyOnly: Boolean? = null,
36+
escapeModelStrings: Boolean? = null,
37+
config: (AjaxLinkContext<T>.() -> Unit)? = null
38+
): AjaxLink<T> {
39+
val context = AjaxLinkContextImpl<T>()
40+
config?.let { it(context) }
41+
val clickHandler = context.onClick
42+
return object : AjaxLink<T>(id, model) {
43+
override fun onClick(target: AjaxRequestTarget) {
44+
clickHandler?.invoke(this, target)
45+
}
46+
}.config(
47+
refType = refType,
48+
visibleWhen = visibleWhen,
49+
enabledWhen = enabledWhen,
50+
renderBodyOnly = renderBodyOnly,
51+
escapeModelStrings = escapeModelStrings,
52+
behaviors = context.behaviors
53+
)
54+
}
55+
56+
/**
57+
* Creates a new [AjaxLink] based on the parameters.
58+
*
59+
* @param T type of [AjaxLink] to create
60+
* @param id Wicket id of the [AjaxLink]
61+
* @param refType how the [AjaxLink] may be updated from the server
62+
* @param visibleWhen model of when the [AjaxLink] is visible
63+
* @param enabledWhen model of when the [AjaxLink] is enabled
64+
* @param renderBodyOnly whether to only render the body of the [AjaxLink]
65+
* @param escapeModelStrings whether to escape the [AjaxLink]'s model string
66+
* @param config lambda for configuring the [AjaxLink]
67+
*/
68+
@Suppress("LongParameterList")
69+
public fun ajaxLink(
70+
id: String,
71+
refType: ComponentReferenceType? = null,
72+
visibleWhen: IModel<Boolean>? = null,
73+
enabledWhen: IModel<Boolean>? = null,
74+
renderBodyOnly: Boolean? = null,
75+
escapeModelStrings: Boolean? = null,
76+
config: (AjaxLinkContext<*>.() -> Unit)? = null
77+
): AjaxLink<*> = ajaxLink<Any?>(
78+
id = id, model = null, refType = refType, visibleWhen = visibleWhen,
79+
enabledWhen = enabledWhen, renderBodyOnly = renderBodyOnly, escapeModelStrings = escapeModelStrings,
80+
config = config
81+
)
82+
}

0 commit comments

Comments
 (0)