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)