From 325b43e394ead7c102f52ccce58094337d3e774e Mon Sep 17 00:00:00 2001 From: kitadai31 <90122968+kitadai31@users.noreply.github.com> Date: Wed, 12 Feb 2025 09:54:06 +0900 Subject: [PATCH] refactor: Improve XML performance (#139) --- .../music/layout/theme/DarkThemePatch.kt | 7 +-- .../materialyou/BaseMaterialYouPatch.kt | 5 +- .../translations/BaseTranslationsPatch.kt | 47 +++++++++---------- .../snackbar/SnackBarComponentsPatch.kt | 8 ++-- .../youtube/layout/theme/ThemePatch.kt | 7 +-- .../youtube/utils/settings/SettingsPatch.kt | 25 +++++----- .../kotlin/app/revanced/util/ResourceUtils.kt | 11 +++-- 7 files changed, 58 insertions(+), 52 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/theme/DarkThemePatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/theme/DarkThemePatch.kt index 45f85b967..3379b60cb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/theme/DarkThemePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/theme/DarkThemePatch.kt @@ -112,10 +112,11 @@ val darkThemePatch = resourcePatch( .valueOrThrow() document("res/values/colors.xml").use { document -> - val resourcesNode = document.getElementsByTagName("resources").item(0) as Element + val resourcesNode = document.documentElement + val childNodes = resourcesNode.childNodes - for (i in 0 until resourcesNode.childNodes.length) { - val node = resourcesNode.childNodes.item(i) as? Element ?: continue + for (i in 0 until childNodes.length) { + val node = childNodes.item(i) as? Element ?: continue val colorName = node.getAttribute("name") if (DARK_COLOR.contains(colorName)) { diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/materialyou/BaseMaterialYouPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/materialyou/BaseMaterialYouPatch.kt index ca07af5af..64255a7a8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/materialyou/BaseMaterialYouPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/materialyou/BaseMaterialYouPatch.kt @@ -37,8 +37,9 @@ private fun ResourcePatchContext.patchXmlFile( val parentList = document.getElementsByTagName(parentNode).item(0) as Element if (targetNode != null) { - for (i in 0 until parentList.childNodes.length) { - val node = parentList.childNodes.item(i) as? Element ?: continue + val childNodes = parentList.childNodes + for (i in 0 until childNodes.length) { + val node = childNodes.item(i) as? Element ?: continue if (node.nodeName == targetNode && node.hasAttribute(attribute)) { node.getAttributeNode(attribute).textContent = newValue diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/translations/BaseTranslationsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/translations/BaseTranslationsPatch.kt index f7f3b8b97..cf65fe09b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/translations/BaseTranslationsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/translations/BaseTranslationsPatch.kt @@ -123,36 +123,35 @@ fun ResourcePatchContext.baseTranslationsPatch( }.toHashSet().toTypedArray() // Remove unselected app languages from RVX Settings - setOf( - "revanced_language_entries", - "revanced_language_entry_values", - ).forEach { attributeName -> - document("res/values/arrays.xml").use { document -> - with(document) { - val nodesToRemove = mutableListOf() + document("res/values/arrays.xml").use { document -> + val targetAttributeNames = setOf( + "revanced_language_entries", + "revanced_language_entry_values", + ) + val nodesToRemove = mutableListOf() - val resourcesNode = getElementsByTagName("resources").item(0) as Element - for (i in 0 until resourcesNode.childNodes.length) { - val node = resourcesNode.childNodes.item(i) as? Element ?: continue + val resourcesNode = document.documentElement + val childNodes = resourcesNode.childNodes + for (i in 0 until childNodes.length) { + val node = childNodes.item(i) as? Element ?: continue - if (node.getAttribute("name") == attributeName) { - for (j in 0 until node.childNodes.length) { - val item = node.childNodes.item(j) as? Element ?: continue - val text = item.textContent - val length = text.length - if (!text.endsWith("DEFAULT") && text.subSequence(length - 2, length) !in filteredAppLanguages) { - nodesToRemove.add(item) - } - } + if (node.getAttribute("name") in targetAttributeNames) { + val itemNodes = node.childNodes + for (j in 0 until itemNodes.length) { + val item = itemNodes.item(j) as? Element ?: continue + val text = item.textContent + val length = text.length + if (!text.endsWith("DEFAULT") && text.subSequence(length - 2, length) !in filteredAppLanguages) { + nodesToRemove.add(item) } } - - // Remove the collected nodes (avoids NullPointerException) - for (n in nodesToRemove) { - n.parentNode?.removeChild(n) - } } } + + // Remove the collected nodes (avoids NullPointerException) + for (n in nodesToRemove) { + n.parentNode?.removeChild(n) + } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/SnackBarComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/SnackBarComponentsPatch.kt index 201632a61..83821d0e9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/SnackBarComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/SnackBarComponentsPatch.kt @@ -348,14 +348,16 @@ val snackBarComponentsPatch = resourcePatch( } document("res/values/dimens.xml").use { document -> - val resourcesNode = document.getElementsByTagName("resources").item(0) as Element + val resourcesNode = document.documentElement + val childNodes = resourcesNode.childNodes - for (i in 0 until resourcesNode.childNodes.length) { - val node = resourcesNode.childNodes.item(i) as? Element ?: continue + for (i in 0 until childNodes.length) { + val node = childNodes.item(i) as? Element ?: continue val dimenName = node.getAttribute("name") if (dimenName.equals("snackbar_corner_radius")) { node.textContent = cornerRadius + break } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt index 8a75f139d..28b2f4446 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt @@ -77,10 +77,11 @@ val themePatch = resourcePatch( arrayOf("values", "values-v31").forEach { path -> document("res/$path/colors.xml").use { document -> - val resourcesNode = document.getElementsByTagName("resources").item(0) as Element + val resourcesNode = document.documentElement + val childNodes = resourcesNode.childNodes - for (i in 0 until resourcesNode.childNodes.length) { - val node = resourcesNode.childNodes.item(i) as? Element ?: continue + for (i in 0 until childNodes.length) { + val node = childNodes.item(i) as? Element ?: continue node.textContent = when (node.getAttribute("name")) { "yt_black0", "yt_black1", "yt_black1_opacity95", "yt_black1_opacity98", "yt_black2", "yt_black3", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt index e3cb03bdd..032dbc5b6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt @@ -223,22 +223,21 @@ val settingsPatch = resourcePatch( /** * remove ReVanced Extended Settings divider */ - arrayOf("Theme.YouTube.Settings", "Theme.YouTube.Settings.Dark").forEach { themeName -> - document("res/values/styles.xml").use { document -> - with(document) { - val resourcesNode = getElementsByTagName("resources").item(0) as Element + document("res/values/styles.xml").use { document -> + val themeNames = arrayOf("Theme.YouTube.Settings", "Theme.YouTube.Settings.Dark") + with(document) { + val resourcesNode = documentElement + val childNodes = resourcesNode.childNodes - val newElement: Element = createElement("item") - newElement.setAttribute("name", "android:listDivider") + for (i in 0 until childNodes.length) { + val node = childNodes.item(i) as? Element ?: continue - for (i in 0 until resourcesNode.childNodes.length) { - val node = resourcesNode.childNodes.item(i) as? Element ?: continue - - if (node.getAttribute("name") == themeName) { - newElement.appendChild(createTextNode("@null")) - - node.appendChild(newElement) + if (node.getAttribute("name") in themeNames) { + val newElement = createElement("item").apply { + setAttribute("name", "android:listDivider") + appendChild(createTextNode("@null")) } + node.appendChild(newElement) } } } diff --git a/patches/src/main/kotlin/app/revanced/util/ResourceUtils.kt b/patches/src/main/kotlin/app/revanced/util/ResourceUtils.kt index 3a1912113..04984db7c 100644 --- a/patches/src/main/kotlin/app/revanced/util/ResourceUtils.kt +++ b/patches/src/main/kotlin/app/revanced/util/ResourceUtils.kt @@ -55,7 +55,8 @@ fun Node.cloneNodes(parent: Node) { */ fun Node.doRecursively(action: (Node) -> Unit) { action(this) - for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action) + val childNodes = this.childNodes + for (i in 0 until childNodes.length) childNodes.item(i).doRecursively(action) } fun List.getResourceGroup(fileNames: Array) = map { directory -> @@ -164,10 +165,11 @@ fun ResourcePatchContext.addEntryValues( ) { document(path).use { document -> with(document) { - val resourcesNode = getElementsByTagName("resources").item(0) as Element + val resourcesNode = documentElement + val childNodes = resourcesNode.childNodes val newElement: Element = createElement("item") - for (i in 0 until resourcesNode.childNodes.length) { - val node = resourcesNode.childNodes.item(i) as? Element ?: continue + for (i in 0 until childNodes.length) { + val node = childNodes.item(i) as? Element ?: continue if (node.getAttribute("name") == attributeName) { newElement.appendChild(createTextNode(attributeValue)) @@ -177,6 +179,7 @@ fun ResourcePatchContext.addEntryValues( } else { node.insertBefore(newElement, node.firstChild) } + break } } }