From 083bd4009231b9612394b4496ca1d329947d6577 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 22 Feb 2024 00:05:41 +0100 Subject: [PATCH] fix: Use deprecated members to ensure backwards compatibility By migrating to early to new APIs of ReVanced Patcher, if you were to use old versions of ReVanced Patcher, you would get compatibility issues. By using deprecated members until most have updated ReVanced Patcher, we can ensure seamless migration. --- api/revanced-patches.api | 1 - .../exportall/ExportAllActivitiesPatch.kt | 4 +- .../gestures/PredictiveBackGesturePatch.kt | 4 +- .../debugging/EnableAndroidDebuggingPatch.kt | 4 +- .../OverrideCertificatePinningPatch.kt | 6 +- .../packagename/ChangePackageNamePatch.kt | 4 +- .../all/misc/resources/AddResourcesPatch.kt | 20 +++-- .../RemoveCaptureRestrictionResourcePatch.kt | 4 +- .../RemoveBroadcastsRestrictionPatch.kt | 4 +- .../reddit/ad/banner/HideBannerPatch.kt | 6 +- .../gms/BaseGmsCoreSupportResourcePatch.kt | 8 +- .../misc/mapping/ResourceMappingPatch.kt | 6 +- .../settings/BaseSettingsResourcePatch.kt | 14 ++-- .../spotify/layout/theme/CustomThemePatch.kt | 8 +- .../misc/dynamiccolor/DynamicColorPatch.kt | 10 ++- .../layout/branding/CustomBrandingPatch.kt | 4 +- .../branding/header/ChangeHeaderPatch.kt | 4 +- .../PlayerControlsBackgroundPatch.kt | 4 +- .../seekbar/SeekbarColorResourcePatch.kt | 4 +- .../sponsorblock/SponsorBlockResourcePatch.kt | 12 +-- .../layout/theme/ThemeResourcePatch.kt | 18 +++-- .../BottomControlsResourcePatch.kt | 41 +++++----- .../misc/settings/SettingsResourcePatch.kt | 12 +-- .../kotlin/app/revanced/util/ResourceUtils.kt | 80 ++++++++++++------- 24 files changed, 174 insertions(+), 108 deletions(-) diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 5423b7edb9..eb4ddd353a 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -1746,7 +1746,6 @@ public final class app/revanced/util/ResourceUtilsKt { public static final fun asSequence (Lorg/w3c/dom/NodeList;)Lkotlin/sequences/Sequence; public static final fun childElementsSequence (Lorg/w3c/dom/Node;)Lkotlin/sequences/Sequence; public static final fun copyResources (Lapp/revanced/patcher/data/ResourceContext;Ljava/lang/String;[Lapp/revanced/util/ResourceGroup;)V - public static final fun copyXmlNode (Ljava/lang/String;Lapp/revanced/patcher/util/Document;Lapp/revanced/patcher/util/Document;)Ljava/lang/AutoCloseable; public static final fun copyXmlNode (Ljava/lang/String;Lapp/revanced/patcher/util/DomFileEditor;Lapp/revanced/patcher/util/DomFileEditor;)Ljava/lang/AutoCloseable; public static final fun doRecursively (Lorg/w3c/dom/Node;Lkotlin/jvm/functions/Function1;)V public static final fun forEachChildElement (Lorg/w3c/dom/Node;Lkotlin/jvm/functions/Function1;)V diff --git a/src/main/kotlin/app/revanced/patches/all/activity/exportall/ExportAllActivitiesPatch.kt b/src/main/kotlin/app/revanced/patches/all/activity/exportall/ExportAllActivitiesPatch.kt index 88bcc6ecee..ccb3246942 100644 --- a/src/main/kotlin/app/revanced/patches/all/activity/exportall/ExportAllActivitiesPatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/activity/exportall/ExportAllActivitiesPatch.kt @@ -14,7 +14,9 @@ object ExportAllActivitiesPatch : ResourcePatch() { private const val EXPORTED_FLAG = "android:exported" override fun execute(context: ResourceContext) { - context.document["AndroidManifest.xml"].use { document -> + context.xmlEditor["AndroidManifest.xml"].use { editor -> + val document = editor.file + val activities = document.getElementsByTagName("activity") for (i in 0..activities.length) { diff --git a/src/main/kotlin/app/revanced/patches/all/interaction/gestures/PredictiveBackGesturePatch.kt b/src/main/kotlin/app/revanced/patches/all/interaction/gestures/PredictiveBackGesturePatch.kt index d0c08751cf..8073bc7df7 100644 --- a/src/main/kotlin/app/revanced/patches/all/interaction/gestures/PredictiveBackGesturePatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/interaction/gestures/PredictiveBackGesturePatch.kt @@ -14,7 +14,9 @@ object PredictiveBackGesturePatch : ResourcePatch() { private const val FLAG = "android:enableOnBackInvokedCallback" override fun execute(context: ResourceContext) { - context.document["AndroidManifest.xml"].use { document -> + context.xmlEditor["AndroidManifest.xml"].use { editor -> + val document = editor.file + with(document.getElementsByTagName("application").item(0)) { if (attributes.getNamedItem(FLAG) != null) return@with diff --git a/src/main/kotlin/app/revanced/patches/all/misc/debugging/EnableAndroidDebuggingPatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/debugging/EnableAndroidDebuggingPatch.kt index 94605fb7ce..4e3dedd329 100644 --- a/src/main/kotlin/app/revanced/patches/all/misc/debugging/EnableAndroidDebuggingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/misc/debugging/EnableAndroidDebuggingPatch.kt @@ -13,7 +13,9 @@ import org.w3c.dom.Element @Suppress("unused") object EnableAndroidDebuggingPatch : ResourcePatch() { override fun execute(context: ResourceContext) { - context.document["AndroidManifest.xml"].use { document -> + context.xmlEditor["AndroidManifest.xml"].use { editor -> + val document = editor.file + val applicationNode = document .getElementsByTagName("application") diff --git a/src/main/kotlin/app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch.kt index 5bf14484dc..20f7142596 100644 --- a/src/main/kotlin/app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch.kt @@ -16,10 +16,12 @@ import java.io.File @Suppress("unused") object OverrideCertificatePinningPatch : ResourcePatch() { override fun execute(context: ResourceContext) { - val resXmlDirectory = context.get("res/xml", false) + val resXmlDirectory = context.get("res/xml") // Add android:networkSecurityConfig="@xml/network_security_config" and the "networkSecurityConfig" attribute if it does not exist. - context.document["AndroidManifest.xml"].use { document -> + context.xmlEditor["AndroidManifest.xml"].use { editor -> + val document = editor.file + val applicationNode = document.getElementsByTagName("application").item(0) as Element if (!applicationNode.hasAttribute("networkSecurityConfig")) { diff --git a/src/main/kotlin/app/revanced/patches/all/misc/packagename/ChangePackageNamePatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/packagename/ChangePackageNamePatch.kt index 63d4bb2a21..f88fda7548 100644 --- a/src/main/kotlin/app/revanced/patches/all/misc/packagename/ChangePackageNamePatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/misc/packagename/ChangePackageNamePatch.kt @@ -52,7 +52,9 @@ object ChangePackageNamePatch : ResourcePatch(), Closeable { } override fun close() = - context.document["AndroidManifest.xml"].use { document -> + context.xmlEditor["AndroidManifest.xml"].use { editor -> + val document = editor.file + val replacementPackageName = packageNameOption.value val manifest = document.getElementsByTagName("manifest").item(0) as Element diff --git a/src/main/kotlin/app/revanced/patches/all/misc/resources/AddResourcesPatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/resources/AddResourcesPatch.kt index 0baf671fc3..0d0ed45f94 100644 --- a/src/main/kotlin/app/revanced/patches/all/misc/resources/AddResourcesPatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/misc/resources/AddResourcesPatch.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.Document +import app.revanced.patcher.util.DomFileEditor import app.revanced.patches.all.misc.resources.AddResourcesPatch.resources import app.revanced.util.* import app.revanced.util.resource.ArrayResource @@ -92,8 +92,10 @@ object AddResourcesPatch : ResourcePatch(), MutableMap + context.xmlEditor[stream].use { editor -> + val document = editor.file + + document.getElementsByTagName("app").asSequence().forEach { app -> val appId = app.attributes.getNamedItem("id").textContent getOrPut(appId, ::mutableMapOf).apply { @@ -237,7 +239,7 @@ object AddResourcesPatch : ResourcePatch(), MutableMap>.invoke( + operator fun MutableMap>.invoke( value: Value, resource: BaseResource, ) { @@ -253,16 +255,18 @@ object AddResourcesPatch : ResourcePatch(), MutableMap + context.xmlEditor[targetFile.path].let { editor -> + val document = editor.file + // Save the target node here as well // in order to avoid having to call document.getNode("resources") // but also save the document so that it can be closed later. - document to document.getNode("resources") + editor to document.getNode("resources") } }.let { (_, targetNode) -> targetNode.addResource(resource) { invoke(value, it) } @@ -276,7 +280,7 @@ object AddResourcesPatch : ResourcePatch(), MutableMap>() + val documents = mutableMapOf>() resources.forEach { resource -> documents(value, resource) } diff --git a/src/main/kotlin/app/revanced/patches/all/screencapture/removerestriction/RemoveCaptureRestrictionResourcePatch.kt b/src/main/kotlin/app/revanced/patches/all/screencapture/removerestriction/RemoveCaptureRestrictionResourcePatch.kt index f38ce36f84..daf597e121 100644 --- a/src/main/kotlin/app/revanced/patches/all/screencapture/removerestriction/RemoveCaptureRestrictionResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/screencapture/removerestriction/RemoveCaptureRestrictionResourcePatch.kt @@ -8,7 +8,9 @@ import org.w3c.dom.Element @Patch(description = "Sets allowAudioPlaybackCapture in manifest to true.") internal object RemoveCaptureRestrictionResourcePatch : ResourcePatch() { override fun execute(context: ResourceContext) { - context.document["AndroidManifest.xml"].use { document -> + context.xmlEditor["AndroidManifest.xml"].use { editor -> + val document = editor.file + // get the application node val applicationNode = document diff --git a/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/RemoveBroadcastsRestrictionPatch.kt b/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/RemoveBroadcastsRestrictionPatch.kt index 7afd506317..70346ec2c2 100644 --- a/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/RemoveBroadcastsRestrictionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/RemoveBroadcastsRestrictionPatch.kt @@ -15,7 +15,9 @@ import org.w3c.dom.Element @Suppress("unused") object RemoveBroadcastsRestrictionPatch : ResourcePatch() { override fun execute(context: ResourceContext) { - context.document["AndroidManifest.xml"].use { document -> + context.xmlEditor["AndroidManifest.xml"].use { editor -> + val document = editor.file + val applicationNode = document .getElementsByTagName("application") diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/banner/HideBannerPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/banner/HideBannerPatch.kt index 4e5a009042..c51216961d 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/ad/banner/HideBannerPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/ad/banner/HideBannerPatch.kt @@ -9,8 +9,10 @@ object HideBannerPatch : ResourcePatch() { private const val RESOURCE_FILE_PATH = "res/layout/merge_listheader_link_detail.xml" override fun execute(context: ResourceContext) { - context.document[RESOURCE_FILE_PATH].use { - it.getElementsByTagName("merge").item(0).childNodes.apply { + context.xmlEditor[RESOURCE_FILE_PATH].use { editor -> + val document = editor.file + + document.getElementsByTagName("merge").item(0).childNodes.apply { val attributes = arrayOf("height", "width") for (i in 1 until length) { diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt index 9e3d1a9abb..e42f33608f 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt @@ -60,7 +60,9 @@ abstract class BaseGmsCoreSupportResourcePatch( appendChild(child) } - document["AndroidManifest.xml"].use { document -> + xmlEditor["AndroidManifest.xml"].use { editor -> + val document = editor.file + val applicationNode = document .getElementsByTagName("application") @@ -92,8 +94,8 @@ abstract class BaseGmsCoreSupportResourcePatch( private fun ResourceContext.patchManifest() { val packageName = ChangePackageNamePatch.setOrGetFallbackPackageName(toPackageName) - val manifest = this.get("AndroidManifest.xml", false).readText() - this.get("AndroidManifest.xml", false).writeText( + val manifest = this.get("AndroidManifest.xml").readText() + this.get("AndroidManifest.xml").writeText( manifest.replace( "package=\"$fromPackageName", "package=\"$packageName", diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt index 9b27144d6b..23831eb415 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt @@ -16,14 +16,16 @@ object ResourceMappingPatch : ResourcePatch() { override fun execute(context: ResourceContext) { // save the file in memory to concurrently read from - val resourceXmlFile = context.get("res/values/public.xml", false).readBytes() + val resourceXmlFile = context.get("res/values/public.xml").readBytes() // create a synchronized list to store the resource mappings val mappings = Collections.synchronizedList(mutableListOf()) for (threadIndex in 0 until THREAD_COUNT) { threadPoolExecutor.execute thread@{ - context.document[resourceXmlFile.inputStream()].use { document -> + context.xmlEditor[resourceXmlFile.inputStream()].use { editor -> + val document = editor.file + val resources = document.documentElement.childNodes val resourcesLength = resources.length val jobSize = resourcesLength / THREAD_COUNT diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/settings/BaseSettingsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/settings/BaseSettingsResourcePatch.kt index 5ad4195c24..8af71dfea2 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/settings/BaseSettingsResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/settings/BaseSettingsResourcePatch.kt @@ -23,8 +23,8 @@ abstract class BaseSettingsResourcePatch( private val rootPreference: Pair? = null, dependencies: Set = emptySet(), ) : ResourcePatch( - dependencies = setOf(AddResourcesPatch::class) + dependencies, - ), + dependencies = setOf(AddResourcesPatch::class) + dependencies, +), MutableSet by mutableSetOf(), Closeable { private lateinit var context: ResourceContext @@ -51,13 +51,17 @@ abstract class BaseSettingsResourcePatch( // Add the root preference to an existing fragment if needed. rootPreference?.let { (intentPreference, fragment) -> - context.document["res/xml/$fragment.xml"].use { - it.getNode("PreferenceScreen").addPreference(intentPreference) + context.xmlEditor["res/xml/$fragment.xml"].use { editor -> + val document = editor.file + + document.getNode("PreferenceScreen").addPreference(intentPreference) } } // Add all preferences to the ReVanced fragment. - context.document["res/xml/revanced_prefs.xml"].use { document -> + context.xmlEditor["res/xml/revanced_prefs.xml"].use { editor -> + val document = editor.file + val revancedPreferenceScreenNode = document.getNode("PreferenceScreen") forEach { revancedPreferenceScreenNode.addPreference(it) } } diff --git a/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt b/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt index 2d839f1689..9418c9f76a 100644 --- a/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt +++ b/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt @@ -43,8 +43,8 @@ object CustomThemePatch : ResourcePatch() { default = "#ff169c46", title = "Pressed dark theme accent color", description = - "The color when accented buttons are pressed, by default slightly darker than accent. " + - "Can be a hex color or a resource reference.", + "The color when accented buttons are pressed, by default slightly darker than accent. " + + "Can be a hex color or a resource reference.", required = true, ) @@ -54,7 +54,9 @@ object CustomThemePatch : ResourcePatch() { val accentColor = accentColor!! val accentColorPressed = accentColorPressed!! - context.document["res/values/colors.xml"].use { document -> + context.xmlEditor["res/values/colors.xml"].use { editor -> + val document = editor.file + val resourcesNode = document.getElementsByTagName("resources").item(0) as Element for (i in 0 until resourcesNode.childNodes.length) { diff --git a/src/main/kotlin/app/revanced/patches/twitter/misc/dynamiccolor/DynamicColorPatch.kt b/src/main/kotlin/app/revanced/patches/twitter/misc/dynamiccolor/DynamicColorPatch.kt index 0b33fdc35b..51d62a9989 100644 --- a/src/main/kotlin/app/revanced/patches/twitter/misc/dynamiccolor/DynamicColorPatch.kt +++ b/src/main/kotlin/app/revanced/patches/twitter/misc/dynamiccolor/DynamicColorPatch.kt @@ -16,7 +16,7 @@ import java.nio.file.Files @Suppress("unused") object DynamicColorPatch : ResourcePatch() { override fun execute(context: ResourceContext) { - val resDirectory = context.get("res", false) + val resDirectory = context.get("res") if (!resDirectory.isDirectory) throw PatchException("The res folder can not be found.") val valuesV31Directory = resDirectory.resolve("values-v31") @@ -35,7 +35,9 @@ object DynamicColorPatch : ResourcePatch() { } } - context.document["res/values-v31/colors.xml"].use { document -> + context.xmlEditor["res/values-v31/colors.xml"].use { editor -> + val document = editor.file + mapOf( "ps__twitter_blue" to "@color/twitter_blue", "ps__twitter_blue_pressed" to "@color/twitter_blue_fill_pressed", @@ -55,7 +57,9 @@ object DynamicColorPatch : ResourcePatch() { } } - context.document["res/values-night-v31/colors.xml"].use { document -> + context.xmlEditor["res/values-night-v31/colors.xml"].use { editor -> + val document = editor.file + mapOf( "twitter_blue" to "@android:color/system_accent1_200", "twitter_blue_fill_pressed" to "@android:color/system_accent1_300", diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt index d0fc001e2c..ec720ec974 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt @@ -81,7 +81,7 @@ object CustomBrandingPatch : ResourcePatch() { }.let { resourceGroups -> if (icon != REVANCED_ICON) { val path = File(icon) - val resourceDirectory = context.get("res", false) + val resourceDirectory = context.get("res") resourceGroups.forEach { group -> val fromDirectory = path.resolve(group.resourceDirectoryName) @@ -102,7 +102,7 @@ object CustomBrandingPatch : ResourcePatch() { appName?.let { name -> // Change the app name. - val manifest = context.get("AndroidManifest.xml", false) + val manifest = context.get("AndroidManifest.xml") manifest.writeText( manifest.readText() .replace( diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt index 61fe82a160..96f8a22aa5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt @@ -71,7 +71,7 @@ object ChangeHeaderPatch : ResourcePatch() { override fun execute(context: ResourceContext) { // The directories to copy the header to. val targetResourceDirectories = targetResourceDirectoryNames.keys.mapNotNull { - context.get("res", false).resolve(it).takeIf(File::exists) + context.get("res").resolve(it).takeIf(File::exists) } // The files to replace in the target directories. val targetResourceFiles = targetResourceDirectoryNames.keys.map { directoryName -> @@ -120,7 +120,7 @@ object ChangeHeaderPatch : ResourcePatch() { // For each source folder, copy the files to the target resource directories. sourceFolders.forEach { dpiSourceFolder -> - val targetDpiFolder = context.get("res", false).resolve(dpiSourceFolder.name) + val targetDpiFolder = context.get("res").resolve(dpiSourceFolder.name) if (!targetDpiFolder.exists()) return@forEach val imgSourceFiles = dpiSourceFolder.listFiles { file -> file.isFile }!! diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt index 8c3d5a7b20..9dcbc49dc8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt @@ -37,7 +37,9 @@ object PlayerControlsBackgroundPatch : ResourcePatch() { private const val RESOURCE_FILE_PATH = "res/drawable/player_button_circle_background.xml" override fun execute(context: ResourceContext) { - context.document[RESOURCE_FILE_PATH].use { document -> + context.xmlEditor[RESOURCE_FILE_PATH].use { editor -> + val document = editor.file + document.doRecursively node@{ node -> if (node !is Element) return@node diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorResourcePatch.kt index cb70ee44ca..09a686be3a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorResourcePatch.kt @@ -29,7 +29,9 @@ internal object SeekbarColorResourcePatch : ResourcePatch() { findColorResource("inline_time_bar_played_not_highlighted_color") // Edit the resume playback drawable and replace the progress bar with a custom drawable - context.document["res/drawable/resume_playback_progressbar_drawable.xml"].use { document -> + context.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { editor -> + val document = editor.file + val layerList = document.getElementsByTagName("layer-list").item(0) as Element val progressNode = layerList.getElementsByTagName("item").item(1) as Element if (!progressNode.getAttributeNode("android:id").value.endsWith("progress")) { diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockResourcePatch.kt index 272ce36e85..335126a843 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockResourcePatch.kt @@ -65,12 +65,14 @@ internal object SponsorBlockResourcePatch : ResourcePatch() { )!! var modifiedControlsLayout = false - val targetDocument = context.document["res/layout/youtube_controls_layout.xml"] + val editor = context.xmlEditor["res/layout/youtube_controls_layout.xml"] "RelativeLayout".copyXmlNode( - context.document[hostingResourceStream], - targetDocument, + context.xmlEditor[hostingResourceStream], + editor, ).also { - val children = targetDocument.getElementsByTagName("RelativeLayout").item(0).childNodes + val document = editor.file + + val children = document.getElementsByTagName("RelativeLayout").item(0).childNodes // Replace the startOf with the voting button view so that the button does not overlap for (i in 1 until children.length) { @@ -82,7 +84,7 @@ internal object SponsorBlockResourcePatch : ResourcePatch() { view.attributes.getNamedItem( "android:id", ).nodeValue.endsWith("live_chat_overlay_button") - ) + ) ) { continue } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeResourcePatch.kt index cf5e351cc9..2d5fef1ebf 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeResourcePatch.kt @@ -35,7 +35,9 @@ internal object ThemeResourcePatch : ResourcePatch() { ) // Edit theme colors via resources. - context.document["res/values/colors.xml"].use { document -> + context.xmlEditor["res/values/colors.xml"].use { editor -> + val document = editor.file + val resourcesNode = document.getElementsByTagName("resources").item(0) as Element val children = resourcesNode.childNodes @@ -76,8 +78,10 @@ internal object ThemeResourcePatch : ResourcePatch() { ) splashScreenResourceFiles.forEach editSplashScreen@{ resourceFile -> - context.document[resourceFile].use { - val layerList = it.getElementsByTagName("layer-list").item(0) as Element + context.xmlEditor[resourceFile].use { editor -> + val document = editor.file + + val layerList = document.getElementsByTagName("layer-list").item(0) as Element val childNodes = layerList.childNodes for (i in 0 until childNodes.length) { @@ -99,11 +103,13 @@ internal object ThemeResourcePatch : ResourcePatch() { colorName: String, colorValue: String, ) { - context.document[resourceFile].use { - val resourcesNode = it.getElementsByTagName("resources").item(0) as Element + context.xmlEditor[resourceFile].use { editor -> + val document = editor.file + + val resourcesNode = document.getElementsByTagName("resources").item(0) as Element resourcesNode.appendChild( - it.createElement("color").apply { + document.createElement("color").apply { setAttribute("name", colorName) setAttribute("category", "color") textContent = colorValue diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch.kt index 4cd94140c6..d2b1c195dc 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch.kt @@ -3,7 +3,7 @@ package app.revanced.patches.youtube.misc.playercontrols import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.Document +import app.revanced.patcher.util.DomFileEditor import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch import java.io.Closeable @@ -18,15 +18,14 @@ object BottomControlsResourcePatch : ResourcePatch(), Closeable { private var lastLeftOf = "fullscreen_button" private lateinit var resourceContext: ResourceContext - private lateinit var targetDocument: Document + private lateinit var targetDocumentEditor: DomFileEditor override fun execute(context: ResourceContext) { resourceContext = context - targetDocument = context.document[TARGET_RESOURCE] + targetDocumentEditor = context.xmlEditor[TARGET_RESOURCE] - bottomUiContainerResourceId = - ResourceMappingPatch.resourceMappings - .single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id + bottomUiContainerResourceId = ResourceMappingPatch.resourceMappings + .single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id } /** @@ -35,21 +34,21 @@ object BottomControlsResourcePatch : ResourcePatch(), Closeable { * @param resourceDirectoryName The name of the directory containing the hosting resource. */ fun addControls(resourceDirectoryName: String) { - val sourceDocument = - resourceContext.document[ - this::class.java.classLoader.getResourceAsStream( - "$resourceDirectoryName/host/layout/$TARGET_RESOURCE_NAME", - )!!, - ] + val sourceDocumentEditor = resourceContext.xmlEditor[ + this::class.java.classLoader.getResourceAsStream( + "$resourceDirectoryName/host/layout/$TARGET_RESOURCE_NAME", + )!!, + ] + val sourceDocument = sourceDocumentEditor.file + val targetDocument = targetDocumentEditor.file - val targetElement = "android.support.constraint.ConstraintLayout" + val targetElementTag = "android.support.constraint.ConstraintLayout" - val hostElements = sourceDocument.getElementsByTagName(targetElement).item(0).childNodes + val sourceElements = sourceDocument.getElementsByTagName(targetElementTag).item(0).childNodes + val targetElement = targetDocument.getElementsByTagName(targetElementTag).item(0) - val destinationElement = targetDocument.getElementsByTagName(targetElement).item(0) - - for (index in 1 until hostElements.length) { - val element = hostElements.item(index).cloneNode(true) + for (index in 1 until sourceElements.length) { + val element = sourceElements.item(index).cloneNode(true) // If the element has no attributes there's no point to adding it to the destination. if (!element.hasAttributes()) continue @@ -65,10 +64,10 @@ object BottomControlsResourcePatch : ResourcePatch(), Closeable { // Add the element. targetDocument.adoptNode(element) - destinationElement.appendChild(element) + targetElement.appendChild(element) } - sourceDocument.close() + sourceDocumentEditor.close() } - override fun close() = targetDocument.close() + override fun close() = targetDocumentEditor.close() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsResourcePatch.kt index 5083cecf58..3fbbc87f7c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsResourcePatch.kt @@ -15,10 +15,10 @@ object SettingsResourcePatch : BaseSettingsResourcePatch( intent = SettingsPatch.newIntent("revanced_settings_intent"), ) to "settings_fragment", dependencies = - setOf( - ResourceMappingPatch::class, - AddResourcesPatch::class, - ), + setOf( + ResourceMappingPatch::class, + AddResourcesPatch::class, + ), ) { // Used for a fingerprint from SettingsPatch. internal var appearanceStringId = -1L @@ -43,7 +43,9 @@ object SettingsResourcePatch : BaseSettingsResourcePatch( // Modify the manifest and add a data intent filter to the LicenseActivity. // Some devices freak out if undeclared data is passed to an intent, // and this change appears to fix the issue. - context.document["AndroidManifest.xml"].use { document -> + context.xmlEditor["AndroidManifest.xml"].use { editor -> + val document = editor.file + // A xml regular-expression would probably work better than this manual searching. val manifestNodes = document.getElementsByTagName("manifest").item(0).childNodes for (i in 0..manifestNodes.length) { diff --git a/src/main/kotlin/app/revanced/util/ResourceUtils.kt b/src/main/kotlin/app/revanced/util/ResourceUtils.kt index 3189f66386..56076078d3 100644 --- a/src/main/kotlin/app/revanced/util/ResourceUtils.kt +++ b/src/main/kotlin/app/revanced/util/ResourceUtils.kt @@ -1,7 +1,6 @@ package app.revanced.util import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.util.Document import app.revanced.patcher.util.DomFileEditor import app.revanced.util.resource.BaseResource import org.w3c.dom.Node @@ -50,7 +49,7 @@ fun ResourceContext.copyResources( sourceResourceDirectory: String, vararg resources: ResourceGroup, ) { - val targetResourceDirectory = this.get("res", false) + val targetResourceDirectory = this.get("res") for (resourceGroup in resources) { resourceGroup.resources.forEach { resource -> @@ -86,28 +85,23 @@ fun ResourceContext.iterateXmlNodeChildren( resource: String, targetTag: String, callback: (node: Node) -> Unit, -) = document[classLoader.getResourceAsStream(resource)!!].use { - val stringsNode = it.getElementsByTagName(targetTag).item(0).childNodes +) = xmlEditor[classLoader.getResourceAsStream(resource)!!].use { editor -> + val document = editor.file + + val stringsNode = document.getElementsByTagName(targetTag).item(0).childNodes for (i in 1 until stringsNode.length - 1) callback(stringsNode.item(i)) } -/** - * Copies the specified node of the source [Document] to the target [Document]. - * @param source the source [Document]. - * @param target the target [Document]- - * @return AutoCloseable that closes the [Document]s. - */ -fun String.copyXmlNode( - source: Document, - target: Document, -): AutoCloseable { - val hostNodes = source.getElementsByTagName(this).item(0).childNodes +// TODO: After the migration to the new patcher, remove the following code and replace it with the commented code below. +fun String.copyXmlNode(source: DomFileEditor, target: DomFileEditor): AutoCloseable { + val hostNodes = source.file.getElementsByTagName(this).item(0).childNodes - val destinationNode = target.getElementsByTagName(this).item(0) + val destinationResourceFile = target.file + val destinationNode = destinationResourceFile.getElementsByTagName(this).item(0) for (index in 0 until hostNodes.length) { val node = hostNodes.item(index).cloneNode(true) - target.adoptNode(node) + destinationResourceFile.adoptNode(node) destinationNode.appendChild(node) } @@ -117,18 +111,44 @@ fun String.copyXmlNode( } } -@Deprecated( - "Use copyXmlNode(Document, Document) instead.", - ReplaceWith( - "this.copyXmlNode(source.file as Document, target.file as Document)", - "app.revanced.patcher.util.Document", - "app.revanced.patcher.util.Document", - ), -) -fun String.copyXmlNode( - source: DomFileEditor, - target: DomFileEditor, -) = this.copyXmlNode(source.file as Document, target.file as Document) +// /** +// * Copies the specified node of the source [Document] to the target [Document]. +// * @param source the source [Document]. +// * @param target the target [Document]- +// * @return AutoCloseable that closes the [Document]s. +// */ +// fun String.copyXmlNode( +// source: Document, +// target: Document, +// ): AutoCloseable { +// val hostNodes = source.getElementsByTagName(this).item(0).childNodes +// +// val destinationNode = target.getElementsByTagName(this).item(0) +// +// for (index in 0 until hostNodes.length) { +// val node = hostNodes.item(index).cloneNode(true) +// target.adoptNode(node) +// destinationNode.appendChild(node) +// } +// +// return AutoCloseable { +// source.close() +// target.close() +// } +// } + +// @Deprecated( +// "Use copyXmlNode(Document, Document) instead.", +// ReplaceWith( +// "this.copyXmlNode(source.file as Document, target.file as Document)", +// "app.revanced.patcher.util.Document", +// "app.revanced.patcher.util.Document", +// ), +// ) +// fun String.copyXmlNode( +// source: DomFileEditor, +// target: DomFileEditor, +// ) = this.copyXmlNode(source.file as Document, target.file as Document) /** * Add a resource node child. @@ -143,4 +163,4 @@ internal fun Node.addResource( appendChild(resource.serialize(ownerDocument, resourceCallback)) } -internal fun Document?.getNode(tagName: String) = this!!.getElementsByTagName(tagName).item(0) +internal fun org.w3c.dom.Document.getNode(tagName: String) = this.getElementsByTagName(tagName).item(0)