2023-01-16 21:36:23 +05:30
|
|
|
package com.github.libretube.util
|
|
|
|
|
|
|
|
import android.text.Editable
|
|
|
|
import android.text.Html
|
2023-01-17 00:20:33 +05:30
|
|
|
import org.xml.sax.Attributes
|
|
|
|
import org.xml.sax.ContentHandler
|
|
|
|
import org.xml.sax.Locator
|
|
|
|
import org.xml.sax.XMLReader
|
|
|
|
|
2023-01-19 21:51:06 +05:30
|
|
|
class HtmlParser(
|
2023-05-09 22:11:05 +05:30
|
|
|
private val handler: LinkHandler,
|
2023-01-19 21:51:06 +05:30
|
|
|
) : Html.TagHandler, ContentHandler {
|
2023-01-16 21:36:23 +05:30
|
|
|
private val tagStatus = ArrayDeque<Boolean>()
|
|
|
|
private var wrapped: ContentHandler? = null
|
|
|
|
private var text: Editable? = null
|
|
|
|
override fun handleTag(opening: Boolean, tag: String, output: Editable, xmlReader: XMLReader) {
|
|
|
|
if (wrapped == null) {
|
|
|
|
// record result object
|
|
|
|
text = output
|
|
|
|
// record current content handler
|
|
|
|
wrapped = xmlReader.contentHandler
|
|
|
|
// replace content handler with our own that forwards to calls to original when needed
|
|
|
|
xmlReader.contentHandler = this
|
2023-01-18 21:43:22 +05:30
|
|
|
// add false to the stack to make sure we always have a tag to pop
|
|
|
|
tagStatus.addLast(false)
|
2023-01-16 21:36:23 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-17 00:20:33 +05:30
|
|
|
override fun startElement(
|
|
|
|
uri: String,
|
|
|
|
localName: String,
|
|
|
|
qName: String,
|
2023-05-09 22:11:05 +05:30
|
|
|
attributes: Attributes,
|
2023-01-17 00:20:33 +05:30
|
|
|
) {
|
2023-01-16 21:36:23 +05:30
|
|
|
val isHandled = handler.handleTag(true, localName, text, attributes)
|
|
|
|
tagStatus.addLast(isHandled)
|
2023-01-18 21:43:22 +05:30
|
|
|
|
2023-01-16 21:36:23 +05:30
|
|
|
if (!isHandled) {
|
|
|
|
wrapped?.startElement(uri, localName, qName, attributes)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-17 00:20:33 +05:30
|
|
|
override fun endElement(uri: String, localName: String, qName: String) {
|
2023-01-16 21:36:23 +05:30
|
|
|
if (!tagStatus.removeLast()) {
|
|
|
|
wrapped?.endElement(uri, localName, qName)
|
|
|
|
}
|
|
|
|
handler.handleTag(false, localName, text, null)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun setDocumentLocator(locator: Locator) {
|
|
|
|
wrapped?.setDocumentLocator(locator)
|
|
|
|
}
|
|
|
|
|
2023-01-17 00:20:33 +05:30
|
|
|
override fun startDocument() {
|
2023-01-16 21:36:23 +05:30
|
|
|
wrapped?.startDocument()
|
|
|
|
}
|
|
|
|
|
2023-01-17 00:20:33 +05:30
|
|
|
override fun endDocument() {
|
2023-01-16 21:36:23 +05:30
|
|
|
wrapped?.endDocument()
|
|
|
|
}
|
|
|
|
|
2023-01-17 00:20:33 +05:30
|
|
|
override fun startPrefixMapping(prefix: String, uri: String) {
|
2023-01-16 21:36:23 +05:30
|
|
|
wrapped?.startPrefixMapping(prefix, uri)
|
|
|
|
}
|
|
|
|
|
2023-01-17 00:20:33 +05:30
|
|
|
override fun endPrefixMapping(prefix: String) {
|
2023-01-16 21:36:23 +05:30
|
|
|
wrapped?.endPrefixMapping(prefix)
|
|
|
|
}
|
|
|
|
|
2023-01-17 00:20:33 +05:30
|
|
|
override fun characters(ch: CharArray, start: Int, length: Int) {
|
2023-01-16 21:36:23 +05:30
|
|
|
wrapped?.characters(ch, start, length)
|
|
|
|
}
|
|
|
|
|
2023-01-17 00:20:33 +05:30
|
|
|
override fun ignorableWhitespace(ch: CharArray, start: Int, length: Int) {
|
2023-01-16 21:36:23 +05:30
|
|
|
wrapped?.ignorableWhitespace(ch, start, length)
|
|
|
|
}
|
|
|
|
|
2023-01-17 00:20:33 +05:30
|
|
|
override fun processingInstruction(target: String, data: String) {
|
2023-01-16 21:36:23 +05:30
|
|
|
wrapped?.processingInstruction(target, data)
|
|
|
|
}
|
|
|
|
|
2023-01-17 00:20:33 +05:30
|
|
|
override fun skippedEntity(name: String) {
|
2023-01-16 21:36:23 +05:30
|
|
|
wrapped?.skippedEntity(name)
|
|
|
|
}
|
2023-01-17 00:20:33 +05:30
|
|
|
}
|