fix(YouTube): Show video chapter titles without clipping when overlay buttons are enabled (#3674)

This commit is contained in:
LisoUseInAIKyrios
2024-09-23 18:50:16 -04:00
committed by GitHub
parent 464e6a3673
commit 317e9a80eb
41 changed files with 537 additions and 273 deletions
@@ -15,6 +15,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
import com.android.tools.smali.dexlib2.iface.reference.Reference
import com.android.tools.smali.dexlib2.util.MethodUtil
import org.stringtemplate.v4.compiler.Bytecode.instructions
fun MethodFingerprint.resultOrThrow() = result ?: throw exception
@@ -73,7 +74,7 @@ fun MutableMethod.injectHideViewCall(
* @param resourceName the name of the resource to find the id for.
* @return the index of the first instruction with the id of the given resource name, or -1 if not found.
* @throws PatchException if the resource cannot be found.
* @see [indexOfIdResourceOrThrow]
* @see [indexOfIdResourceOrThrow], [indexOfFirstWideLiteralInstructionValueReversed]
*/
fun Method.indexOfIdResource(resourceName: String): Int {
val resourceId = ResourceMappingPatch["id", resourceName]
@@ -86,6 +87,7 @@ fun Method.indexOfIdResource(resourceName: String): Int {
* Requires [ResourceMappingPatch] as a dependency.
*
* @throws [PatchException] if the resource is not found, or the method does not contain the resource id literal value.
* @see [indexOfIdResource], [indexOfFirstWideLiteralInstructionValueReversedOrThrow]
*/
fun Method.indexOfIdResourceOrThrow(resourceName: String): Int {
val index = indexOfIdResource(resourceName)
@@ -120,6 +122,30 @@ fun Method.indexOfFirstWideLiteralInstructionValueOrThrow(literal: Long): Int {
return index
}
/**
* Find the index of the last wide literal instruction with the given value.
*
* @return the last literal instruction with the value, or -1 if not found.
* @see indexOfFirstWideLiteralInstructionValueOrThrow
*/
fun Method.indexOfFirstWideLiteralInstructionValueReversed(literal: Long) = implementation?.let {
it.instructions.indexOfLast { instruction ->
(instruction as? WideLiteralInstruction)?.wideLiteral == literal
}
} ?: -1
/**
* Find the index of the last wide literal instruction with the given value,
* or throw an exception if not found.
*
* @return the last literal instruction with the value, or throws [PatchException] if not found.
*/
fun Method.indexOfFirstWideLiteralInstructionValueReversedOrThrow(literal: Long): Int {
val index = indexOfFirstWideLiteralInstructionValueReversed(literal)
if (index < 0) throw PatchException("Could not find literal value: $literal")
return index
}
/**
* Check if the method contains a literal with the given value.
*
@@ -1,8 +1,11 @@
package app.revanced.util
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.util.DomFileEditor
import app.revanced.util.resource.BaseResource
import org.w3c.dom.Attr
import org.w3c.dom.Element
import org.w3c.dom.Node
import org.w3c.dom.NodeList
import java.io.InputStream
@@ -39,6 +42,14 @@ fun Node.doRecursively(action: (Node) -> Unit) {
for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action)
}
fun Node.insertFirst(node: Node) {
if (hasChildNodes()) {
insertBefore(node, firstChild)
} else {
appendChild(node)
}
}
/**
* Copy resources from the current class loader to the resource directory.
*
@@ -49,7 +60,7 @@ fun ResourceContext.copyResources(
sourceResourceDirectory: String,
vararg resources: ResourceGroup,
) {
val targetResourceDirectory = this.get("res")
val targetResourceDirectory = this["res", false]
for (resourceGroup in resources) {
resourceGroup.resources.forEach { resource ->
@@ -164,3 +175,37 @@ internal fun Node.addResource(
}
internal fun org.w3c.dom.Document.getNode(tagName: String) = this.getElementsByTagName(tagName).item(0)
internal fun NodeList.findElementByAttributeValue(attributeName: String, value: String): Element? {
for (i in 0 until length) {
val node = item(i)
if (node.nodeType == Node.ELEMENT_NODE) {
val element = node as Element
if (element.getAttribute(attributeName) == value) {
return element
}
// Recursively search.
val found = element.childNodes.findElementByAttributeValue(attributeName, value)
if (found != null) {
return found
}
}
}
return null
}
internal fun NodeList.findElementByAttributeValueOrThrow(attributeName: String, value: String): Element {
return findElementByAttributeValue(attributeName, value) ?: throw PatchException("Could not find: $attributeName $value")
}
internal fun Element.copyAttributesFrom(oldContainer: Element) {
// Copy attributes from the old element to the new element
val attributes = oldContainer.attributes
for (i in 0 until attributes.length) {
val attr = attributes.item(i) as Attr
setAttribute(attr.name, attr.value)
}
}