Skip to content
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 @@ -461,11 +461,12 @@ object FuzzyAttributeParser {
}

private fun cleanSpDimension(value: String): String {
val fixedUnit = value.lowercase()
val normalized = value.lowercase()
.replace(" ", "")
.replace(Regex("5p$"), "sp")
val numericCandidate = normalized
.replace(Regex("(sp|5p)$"), "")

val numericString = fixedUnit.replace("_", "")
val numericString = numericCandidate.replace("_", "")
val numericPart = extractOcrNumber(numericString)

if (numericPart != null) return "${numericPart}sp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ object PassThroughValidator : AttributeValidator {
override fun validate(rawValue: String): String = rawValue.trim()
}

object BooleanValidator : AttributeValidator {
private val allowedValues = listOf("true", "false")

override fun validate(rawValue: String): String? {
return matchCategoricalValue(rawValue.trim().lowercase(), allowedValues, threshold = 85)
}
}

object DimensionValidator : AttributeValidator {
private val dimensionValues = listOf("match_parent", "wrap_content")

Expand All @@ -28,6 +36,22 @@ object DimensionValidator : AttributeValidator {
}
}

class SpDimensionRangeValidator(
private val minSp: Int,
private val maxSp: Int
) : AttributeValidator {
private val spRegex = Regex("^(\\d+(?:\\.\\d+)?)sp$")

override fun validate(rawValue: String): String? {
val trimmed = rawValue.trim()

val match = spRegex.matchEntire(trimmed) ?: return null
val value = match.groupValues[1].toFloatOrNull() ?: return null

return trimmed.takeIf { value >= minSp && value <= maxSp }
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

class CategoricalValidator(private val allowedValues: List<String>) : AttributeValidator {
override fun validate(rawValue: String): String? {
return matchCategoricalValue(rawValue.trim(), allowedValues)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ class UiGrammarValidator {
SpinnerGrammar,
ImageViewGrammar,
EditTextGrammar,
RadioButtonGrammar,
CheckBoxGrammar,
SwitchGrammar,
RadioGroupGrammar,
SliderGrammar
).associateBy { it.tag }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,106 @@ package org.appdevforall.codeonthego.computervision.domain.grammar

import org.appdevforall.codeonthego.computervision.domain.FuzzyAttributeParser.AttributeKey


interface WidgetGrammar {
val tag: String
val attributes: Map<String, AttributeValidator>
get() = mapOf(
AttributeKey.WIDTH.xmlName to DimensionValidator,
AttributeKey.HEIGHT.xmlName to DimensionValidator,
AttributeKey.ID.xmlName to PassThroughValidator
)
}

interface LayoutGrammar : WidgetGrammar {
override val attributes: Map<String, AttributeValidator>
get() = super.attributes + mapOf(
AttributeKey.LAYOUT_MARGIN.xmlName to DimensionValidator,
AttributeKey.LAYOUT_MARGIN_TOP.xmlName to DimensionValidator,
AttributeKey.LAYOUT_MARGIN_BOTTOM.xmlName to DimensionValidator,
AttributeKey.LAYOUT_MARGIN_START.xmlName to DimensionValidator,
AttributeKey.LAYOUT_MARGIN_END.xmlName to DimensionValidator,
AttributeKey.LAYOUT_GRAVITY.xmlName to PassThroughValidator,
AttributeKey.LAYOUT_WEIGHT.xmlName to PassThroughValidator,
AttributeKey.PADDING.xmlName to DimensionValidator,
AttributeKey.VISIBILITY.xmlName to CategoricalValidator(listOf("visible", "invisible", "gone"))
)
}

interface TextGrammar : LayoutGrammar {
override val attributes: Map<String, AttributeValidator>
get() = super.attributes + mapOf(
AttributeKey.TEXT_COLOR.xmlName to PassThroughValidator,
AttributeKey.TEXT_SIZE.xmlName to PassThroughValidator,
AttributeKey.TEXT_STYLE.xmlName to PassThroughValidator,
AttributeKey.TEXT_ALIGNMENT.xmlName to PassThroughValidator,
AttributeKey.FONT_FAMILY.xmlName to PassThroughValidator
)
}

object SpinnerGrammar : WidgetGrammar {
interface CompoundButtonGrammar : TextGrammar {
override val attributes: Map<String, AttributeValidator>
get() = super.attributes + mapOf(
AttributeKey.TEXT.xmlName to PassThroughValidator,
AttributeKey.CHECKED.xmlName to BooleanValidator,
AttributeKey.TEXT_SIZE.xmlName to SpDimensionRangeValidator(minSp = 8, maxSp = 32)
)
}


object SpinnerGrammar : LayoutGrammar {
override val tag = "Spinner"
override val attributes = mapOf(
AttributeKey.WIDTH.xmlName to DimensionValidator,
AttributeKey.HEIGHT.xmlName to DimensionValidator,
AttributeKey.ID.xmlName to PassThroughValidator,
override val attributes = super.attributes + mapOf(
AttributeKey.TEXT.xmlName to PassThroughValidator,
AttributeKey.ENTRIES.xmlName to EntriesValidator
)
}

object ImageViewGrammar : WidgetGrammar {
object ImageViewGrammar : LayoutGrammar {
override val tag = "ImageView"
private val gravityValues = listOf("top", "bottom", "left", "right", "center", "center_vertical", "center_horizontal", "start", "end")

override val attributes = mapOf(
AttributeKey.WIDTH.xmlName to DimensionValidator,
AttributeKey.HEIGHT.xmlName to DimensionValidator,
AttributeKey.ID.xmlName to PassThroughValidator,
override val attributes = super.attributes + mapOf(
AttributeKey.SRC.xmlName to PassThroughValidator,
AttributeKey.LAYOUT_GRAVITY.xmlName to CategoricalValidator(gravityValues)
)
}

object EditTextGrammar : WidgetGrammar {
object EditTextGrammar : TextGrammar {
override val tag = "EditText"
private val inputTypeValues = listOf("text", "textPassword", "number", "numberDecimal", "textEmailAddress", "textUri", "phone")

override val attributes = mapOf(
AttributeKey.WIDTH.xmlName to DimensionValidator,
AttributeKey.HEIGHT.xmlName to DimensionValidator,
AttributeKey.ID.xmlName to PassThroughValidator,
override val attributes = super.attributes + mapOf(
AttributeKey.TEXT.xmlName to PassThroughValidator,
AttributeKey.INPUT_TYPE.xmlName to CategoricalValidator(inputTypeValues),
AttributeKey.HINT.xmlName to PassThroughValidator
)
}

object SliderGrammar : WidgetGrammar {
object RadioButtonGrammar : CompoundButtonGrammar {
override val tag = "RadioButton"
}

object CheckBoxGrammar : CompoundButtonGrammar {
override val tag = "CheckBox"
}

object SwitchGrammar : CompoundButtonGrammar {
override val tag = "Switch"
}

object RadioGroupGrammar : TextGrammar {
override val tag = "RadioGroup"
override val attributes = super.attributes + mapOf(
AttributeKey.ORIENTATION.xmlName to CategoricalValidator(listOf("horizontal", "vertical")),
AttributeKey.TEXT_SIZE.xmlName to SpDimensionRangeValidator(minSp = 8, maxSp = 32)
)
}

object SliderGrammar : LayoutGrammar {
override val tag = "com.google.android.material.slider.Slider"
override val attributes = mapOf(
AttributeKey.WIDTH.xmlName to DimensionValidator,
AttributeKey.HEIGHT.xmlName to DimensionValidator,
AttributeKey.ID.xmlName to PassThroughValidator,
override val attributes = super.attributes + mapOf(
AttributeKey.TEXT.xmlName to PassThroughValidator,
AttributeKey.LAYOUT_WEIGHT.xmlName to PassThroughValidator,
AttributeKey.STYLE.xmlName to SliderStyleValidator
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.appdevforall.codeonthego.computervision.domain.xml


object AndroidConstants {
const val MATCH_PARENT = "match_parent"
const val WRAP_CONTENT = "wrap_content"

const val ORIENTATION_HORIZONTAL = "horizontal"

const val TRUE = "true"
const val FALSE = "false"

const val DEFAULT_TEXT_SIZE = "16sp"
}

object AndroidWidgetTags {
const val LINEAR_LAYOUT = "LinearLayout"
const val RADIO_GROUP = "RadioGroup"

const val TEXT_VIEW = "TextView"
const val BUTTON = "Button"
const val IMAGE_VIEW = "ImageView"
const val CHECK_BOX = "CheckBox"
const val RADIO_BUTTON = "RadioButton"
const val SWITCH = "Switch"
const val EDIT_TEXT = "EditText"
const val SPINNER = "Spinner"
const val SEEK_BAR = "SeekBar"
const val VIEW = "View"
}
Loading
Loading