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 5423b7edb..eb4ddd353 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 88bcc6ece..ccb324694 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 d0c08751c..8073bc7df 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 94605fb7c..4e3dedd32 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 5bf14484d..20f714259 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 63d4bb2a2..f88fda754 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 0baf671fc..0d0ed45f9 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 f38ce36f8..daf597e12 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 7afd50631..70346ec2c 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 4e5a00904..c51216961 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 9e3d1a9ab..e42f33608 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 9b27144d6..23831eb41 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 5ad4195c2..8af71dfea 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 2d839f168..9418c9f76 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 0b33fdc35..51d62a998 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 d0fc001e2..ec720ec97 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 61fe82a16..96f8a22aa 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 8c3d5a7b2..9dcbc49dc 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 cb70ee44c..09a686be3 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 272ce36e8..335126a84 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 cf5e351cc..2d5fef1eb 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 4cd94140c..d2b1c195d 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 5083cecf5..3fbbc87f7 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 3189f6638..56076078d 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)