diff --git a/cv-image-to-xml/src/main/java/org/appdevforall/codeonthego/computervision/domain/MarginAnnotationParser.kt b/cv-image-to-xml/src/main/java/org/appdevforall/codeonthego/computervision/domain/MarginAnnotationParser.kt index b767b9054d..7ab86088a5 100644 --- a/cv-image-to-xml/src/main/java/org/appdevforall/codeonthego/computervision/domain/MarginAnnotationParser.kt +++ b/cv-image-to-xml/src/main/java/org/appdevforall/codeonthego/computervision/domain/MarginAnnotationParser.kt @@ -125,7 +125,7 @@ object MarginAnnotationParser { for (block in explicitBlocks) { val tag = block.tag ?: continue - if (canvasTags.any { (canvasTag, _) -> canvasTag == tag }) { + if (canvasTags.isEmpty() || canvasTags.any { (canvasTag, _) -> canvasTag == tag }) { annotationMap[tag] = block.annotationText } } diff --git a/cv-image-to-xml/src/main/java/org/appdevforall/codeonthego/computervision/domain/xml/AndroidWidget.kt b/cv-image-to-xml/src/main/java/org/appdevforall/codeonthego/computervision/domain/xml/AndroidWidget.kt index 5c8cb6cc0b..0c28f67adb 100644 --- a/cv-image-to-xml/src/main/java/org/appdevforall/codeonthego/computervision/domain/xml/AndroidWidget.kt +++ b/cv-image-to-xml/src/main/java/org/appdevforall/codeonthego/computervision/domain/xml/AndroidWidget.kt @@ -88,20 +88,51 @@ class SpinnerWidget( override fun processAttributes(context: XmlContext, id: String, attrs: Map): Map { val processed = mutableMapOf() + val rawEntries = attrs[AttributeKey.ENTRIES.xmlName] + ?: attrs[AttributeKey.TEXT.xmlName] + ?: box.text.takeIf { it.isMeaningfulDropdownText() } + + when { + rawEntries == null -> Unit + rawEntries.trimStart().startsWith("@") -> { + processed[AttributeKey.ENTRIES.xmlName] = rawEntries.trim().escapeXmlAttr() + } + else -> rawEntries + .toSpinnerEntries() + .takeIf { it.isNotEmpty() } + ?.let { items -> + val arrayName = "${id}_array" + context.stringArrays[arrayName] = items + processed[AttributeKey.ENTRIES.xmlName] = "@array/$arrayName" + } + } attrs.forEach { (key, value) -> - if (key == AttributeKey.ENTRIES.xmlName && !value.startsWith("@")) { - val arrayName = "${id}_array" - val items = value.split(",").map { it.trim() }.filter { it.isNotEmpty() } - - context.stringArrays[arrayName] = items - processed[key] = "@array/$arrayName" - } else { - processed[key] = value.escapeXmlAttr() + when { + key == AttributeKey.ENTRIES.xmlName || key == AttributeKey.TEXT.xmlName -> Unit + else -> processed[key] = value.escapeXmlAttr() } } return processed } + + private fun String.toSpinnerEntries(): List { + return removeTrailingDropdownGlyph() + .split(Regex("\\s*[,;|/\\n]+\\s*")) + .map { it.trim() } + .filter { it.isNotEmpty() } + } + + private fun String.removeTrailingDropdownGlyph(): String { + return trim() + .replace(Regex("\\s*[▼▽▾▿⌄˅∨]$|\\s+[vV]$"), "") + .trim() + } + + private fun String.isMeaningfulDropdownText(): Boolean { + val cleaned = removeTrailingDropdownGlyph() + return cleaned.isNotBlank() && !cleaned.equals("dropdown", ignoreCase = true) + } } class TextBasedWidget( diff --git a/cv-image-to-xml/src/main/java/org/appdevforall/codeonthego/computervision/utils/MetadataDetector.kt b/cv-image-to-xml/src/main/java/org/appdevforall/codeonthego/computervision/utils/MetadataDetector.kt index 416e380632..68cee4064a 100644 --- a/cv-image-to-xml/src/main/java/org/appdevforall/codeonthego/computervision/utils/MetadataDetector.kt +++ b/cv-image-to-xml/src/main/java/org/appdevforall/codeonthego/computervision/utils/MetadataDetector.kt @@ -31,17 +31,13 @@ object MetadataDetector { ) private val xmlAttributeRegex = Regex("""\b(?:android|app|tools):[a-zA-Z_]+\b""") - private val assignmentRegex = Regex("""\b[a-zA-Z_]+(?:[:=])[^\s]+""") - fun isCanvasMetadata(text: String): Boolean { val lowerText = text.lowercase() if (lowerText.isBlank()) return false if (metadataSnippets.any { snippet -> lowerText.contains(snippet) }) return true if (xmlAttributeRegex.containsMatchIn(lowerText)) return true if (metadataKeywords.any { keyword -> lowerText.contains(keyword) }) return true - - val assignmentCount = assignmentRegex.findAll(lowerText).count() - return assignmentCount >= 2 + return false } fun isMetadataLabel(label: String): Boolean {