From 0738355d492ef931581a7c598e0528b49b78734e Mon Sep 17 00:00:00 2001 From: sabeeh Date: Thu, 23 Nov 2023 22:46:50 +0400 Subject: [PATCH 01/10] fix constraint input stream --- .../com/fleeksoft/ksoup/helper/DataUtil.kt | 18 +++++++++++++----- .../com/fleeksoft/ksoup/helper/DataUtilTest.kt | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/helper/DataUtil.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/helper/DataUtil.kt index c94c9e87..54e17233 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/helper/DataUtil.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/helper/DataUtil.kt @@ -1,6 +1,7 @@ package com.fleeksoft.ksoup.helper import com.fleeksoft.ksoup.UncheckedIOException +import com.fleeksoft.ksoup.internal.ConstrainableSource import com.fleeksoft.ksoup.internal.Normalizer import com.fleeksoft.ksoup.internal.StringUtil import com.fleeksoft.ksoup.nodes.Comment @@ -30,7 +31,7 @@ internal object DataUtil { val UTF_8: Charset = Charsets.UTF_8 // Don't use StandardCharsets, as those only appear in Android API 19, and we target 10. private val defaultCharsetName: String = UTF_8.name // used if not found in header or meta charset - private const val firstReadBufferSize = 1024 * 5 + private const val firstReadBufferSize: Long = (1024 * 5).toLong() private const val bufferSize: Long = (1024 * 32).toLong() private val mimeBoundaryChars = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray() @@ -155,7 +156,7 @@ internal object DataUtil { * @throws IOException on IO error */ @Throws(IOException::class) - fun crossStreams(source: ByteArray, outSource: okio.Buffer) { + fun crossStreams(source: ByteArray, outSource: Buffer) { outSource.write(source) } @@ -179,7 +180,7 @@ internal object DataUtil { val peekedBuffer = bufferReader.getPeek() // -1 because we read one more to see if completed. First read is < buffer size, so can't be invalid. - val firstBytes: ByteArray = readToByteBuffer(peekedBuffer) + val firstBytes: ByteArray = readToByteBuffer(peekedBuffer, firstReadBufferSize - 1) val fullyRead = peekedBuffer.exhausted() peekedBuffer.close() @@ -303,8 +304,15 @@ internal object DataUtil { * @throws IOException if an exception occurs whilst reading from the input stream. */ @Throws(IOException::class) - fun readToByteBuffer(bufferReader: BufferedSource): ByteArray { - return bufferReader.readByteArray() + fun readToByteBuffer(bufferReader: BufferedSource, maxSize: Long): ByteArray { + require(maxSize >= 0) { + "maxSize must be 0 (unlimited) or larger" + } + return if (maxSize == 0L) { + bufferReader.readByteArray() + } else { + ConstrainableSource.wrap(BufferReader(bufferReader), maxSize.toInt()).readToByteBuffer(maxSize.toInt()).readByteArray() + } /*Validate.isTrue(maxSize >= 0, "maxSize must be 0 (unlimited) or larger") val calculatedMaxSize: Int = if (bufferReader.size() > 0) bufferReader.size().toInt() else maxSize diff --git a/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/helper/DataUtilTest.kt b/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/helper/DataUtilTest.kt index 34264e51..a1154d66 100644 --- a/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/helper/DataUtilTest.kt +++ b/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/helper/DataUtilTest.kt @@ -273,7 +273,7 @@ class DataUtilTest { fun handlesUnlimitedRead() { val inputFile: String = ParseTest.getResourceAbsolutePath("htmltests/large.html") val input: String = ParseTest.getFileAsString(inputFile.toPath()) - val byteBuffer: ByteArray = DataUtil.readToByteBuffer(input.toBuffer()) + val byteBuffer: ByteArray = DataUtil.readToByteBuffer(input.toBuffer(), 0) val read = byteBuffer.decodeToString() assertEquals(input, read) } From ccf8ecc9705e0e5c63230ac670c65f57f9335a42 Mon Sep 17 00:00:00 2001 From: sabeeh Date: Fri, 24 Nov 2023 01:23:47 +0400 Subject: [PATCH 02/10] ksoup-network test add ksoup dependency --- ksoup-network/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/ksoup-network/build.gradle.kts b/ksoup-network/build.gradle.kts index e9b2c3a7..4a27278c 100644 --- a/ksoup-network/build.gradle.kts +++ b/ksoup-network/build.gradle.kts @@ -41,6 +41,7 @@ kotlin { } commonTest.dependencies { implementation(libs.kotlin.test) + implementation(projects.ksoup) } jvmMain.dependencies { From a94fb9fddfeb8f707f14d6acbd063785a38d7e51 Mon Sep 17 00:00:00 2001 From: sabeeh Date: Fri, 24 Nov 2023 01:24:48 +0400 Subject: [PATCH 03/10] fix Wrong location for redirects issue #3 --- .../ksoup/network/Platform.android.kt | 6 +--- .../fleeksoft/ksoup/network/KsoupNetwork.kt | 36 ++++++++++++------- .../fleeksoft/ksoup/network/NetworkHelper.kt | 10 +++++- .../fleeksoft/ksoup/network/Platform.jvm.kt | 3 -- 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/ksoup-network/src/androidMain/kotlin/com/fleeksoft/ksoup/network/Platform.android.kt b/ksoup-network/src/androidMain/kotlin/com/fleeksoft/ksoup/network/Platform.android.kt index 3b9f1618..08908da4 100644 --- a/ksoup-network/src/androidMain/kotlin/com/fleeksoft/ksoup/network/Platform.android.kt +++ b/ksoup-network/src/androidMain/kotlin/com/fleeksoft/ksoup/network/Platform.android.kt @@ -4,9 +4,5 @@ import io.ktor.client.engine.HttpClientEngine import io.ktor.client.engine.okhttp.OkHttp internal actual fun provideHttpClientEngine(): HttpClientEngine { - return OkHttp.create { - config { - followRedirects(true) - } - } + return OkHttp.create {} } \ No newline at end of file diff --git a/ksoup-network/src/commonMain/kotlin/com/fleeksoft/ksoup/network/KsoupNetwork.kt b/ksoup-network/src/commonMain/kotlin/com/fleeksoft/ksoup/network/KsoupNetwork.kt index e77b7bf6..f31fb837 100644 --- a/ksoup-network/src/commonMain/kotlin/com/fleeksoft/ksoup/network/KsoupNetwork.kt +++ b/ksoup-network/src/commonMain/kotlin/com/fleeksoft/ksoup/network/KsoupNetwork.kt @@ -12,7 +12,7 @@ import kotlinx.coroutines.runBlocking * * Use examples: * - * * `Document doc = Ksoup.parseGetRequest("http://example.com");` + * * `Document doc = Ksoup.parseGetRequest("http://example.com")` * * @param url URL to connect to. The protocol must be `http` or `https`. * @return sane HTML @@ -23,10 +23,14 @@ public fun Ksoup.parseGetRequest( httpRequestBuilder: HttpRequestBuilder.() -> Unit = {}, parser: Parser = Parser.htmlParser(), ): Document { - val result: String = runBlocking { - NetworkHelper.instance.get(url, httpRequestBuilder = httpRequestBuilder).bodyAsText() + var finalUrl: String = url + val response: String = runBlocking { + val httpResponse = NetworkHelper.instance.get(finalUrl, httpRequestBuilder = httpRequestBuilder) +// url can be changed after redirection + finalUrl = httpResponse.request.url.toString() + httpResponse.bodyAsText() } - return parse(html = result, parser = parser, baseUri = url) + return parse(html = response, parser = parser, baseUri = finalUrl) } /** @@ -34,7 +38,7 @@ public fun Ksoup.parseGetRequest( * * Use examples: * - * * `Document doc = Ksoup.parseSubmitRequest("http://example.com", params = mapOf("param1Key" to "param1Value")) + * * `Document doc = Ksoup.parseSubmitRequest("http://example.com", params = mapOf("param1Key" to "param1Value"))` * * @param url URL to connect to. The protocol must be `http` or `https`. * @return sane HTML @@ -46,15 +50,19 @@ public fun Ksoup.parseSubmitRequest( httpRequestBuilder: HttpRequestBuilder.() -> Unit = {}, parser: Parser = Parser.htmlParser(), ): Document { + var finalUrl = url val result: String = runBlocking { - NetworkHelper.instance.submitForm( + val httpResponse = NetworkHelper.instance.submitForm( url = url, params = params, httpRequestBuilder = httpRequestBuilder - ).bodyAsText() + ) +// url can be changed after redirection + finalUrl = httpResponse.request.url.toString() + httpResponse.bodyAsText() } - return parse(html = result, parser = parser, baseUri = url) + return parse(html = result, parser = parser, baseUri = finalUrl) } @@ -63,7 +71,7 @@ public fun Ksoup.parseSubmitRequest( * * Use examples: * - * * `Document doc = Ksoup.parsePostRequest("http://example.com");` + * * `Document doc = Ksoup.parsePostRequest("http://example.com")` * * @param url URL to connect to. The protocol must be `http` or `https`. * @return sane HTML @@ -74,12 +82,16 @@ public fun Ksoup.parsePostRequest( httpRequestBuilder: HttpRequestBuilder.() -> Unit = {}, parser: Parser = Parser.htmlParser(), ): Document { + var finalUrl = url val result: String = runBlocking { - NetworkHelper.instance.post( + val httpResponse = NetworkHelper.instance.post( url = url, httpRequestBuilder = httpRequestBuilder - ).bodyAsText() + ) +// url can be changed after redirection + finalUrl = httpResponse.request.url.toString() + httpResponse.bodyAsText() } - return parse(html = result, parser = parser, baseUri = url) + return parse(html = result, parser = parser, baseUri = finalUrl) } \ No newline at end of file diff --git a/ksoup-network/src/commonMain/kotlin/com/fleeksoft/ksoup/network/NetworkHelper.kt b/ksoup-network/src/commonMain/kotlin/com/fleeksoft/ksoup/network/NetworkHelper.kt index 1e61f6df..13d44fde 100644 --- a/ksoup-network/src/commonMain/kotlin/com/fleeksoft/ksoup/network/NetworkHelper.kt +++ b/ksoup-network/src/commonMain/kotlin/com/fleeksoft/ksoup/network/NetworkHelper.kt @@ -1,15 +1,23 @@ package com.fleeksoft.ksoup.network import io.ktor.client.HttpClient +import io.ktor.client.plugins.* +import io.ktor.client.plugins.observer.* import io.ktor.client.request.* import io.ktor.client.request.forms.submitForm import io.ktor.client.statement.HttpResponse import io.ktor.http.parameters +import io.ktor.utils.io.core.* internal class NetworkHelper(private val client: HttpClient) { companion object { - val instance: NetworkHelper = NetworkHelper(HttpClient(provideHttpClientEngine())) + val instance: NetworkHelper = NetworkHelper(HttpClient(provideHttpClientEngine()) { + this.followRedirects = true + /*this.ResponseObserver { + println("headers => ${it.headers}") + }*/ + }) } suspend fun get( diff --git a/ksoup-network/src/jvmMain/kotlin/com/fleeksoft/ksoup/network/Platform.jvm.kt b/ksoup-network/src/jvmMain/kotlin/com/fleeksoft/ksoup/network/Platform.jvm.kt index 3b9f1618..eec70b2e 100644 --- a/ksoup-network/src/jvmMain/kotlin/com/fleeksoft/ksoup/network/Platform.jvm.kt +++ b/ksoup-network/src/jvmMain/kotlin/com/fleeksoft/ksoup/network/Platform.jvm.kt @@ -5,8 +5,5 @@ import io.ktor.client.engine.okhttp.OkHttp internal actual fun provideHttpClientEngine(): HttpClientEngine { return OkHttp.create { - config { - followRedirects(true) - } } } \ No newline at end of file From 316d779601829d1047cc163a956239b9c392762e Mon Sep 17 00:00:00 2001 From: sabeeh Date: Fri, 24 Nov 2023 01:46:00 +0400 Subject: [PATCH 04/10] code optimize --- .../androidMain/kotlin/com/fleeksoft/ksoup/Platform.android.kt | 2 +- ksoup/src/iosMain/kotlin/com/fleeksoft/ksoup/Platform.ios.kt | 2 +- ksoup/src/jvmMain/kotlin/com/fleeksoft/ksoup/Platform.jvm.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ksoup/src/androidMain/kotlin/com/fleeksoft/ksoup/Platform.android.kt b/ksoup/src/androidMain/kotlin/com/fleeksoft/ksoup/Platform.android.kt index f55caee3..081fc578 100644 --- a/ksoup/src/androidMain/kotlin/com/fleeksoft/ksoup/Platform.android.kt +++ b/ksoup/src/androidMain/kotlin/com/fleeksoft/ksoup/Platform.android.kt @@ -7,7 +7,7 @@ import okio.Path import okio.buffer internal actual fun readGzipFile(file: Path): BufferedSource { - val fileSource = FileSystem.SYSTEM.source(file) + val fileSource = readFile(file) return GzipSource(source = fileSource).buffer() } diff --git a/ksoup/src/iosMain/kotlin/com/fleeksoft/ksoup/Platform.ios.kt b/ksoup/src/iosMain/kotlin/com/fleeksoft/ksoup/Platform.ios.kt index fe612341..a4c00676 100644 --- a/ksoup/src/iosMain/kotlin/com/fleeksoft/ksoup/Platform.ios.kt +++ b/ksoup/src/iosMain/kotlin/com/fleeksoft/ksoup/Platform.ios.kt @@ -8,7 +8,7 @@ import okio.buffer internal actual fun readGzipFile(file: Path): BufferedSource { return Buffer().apply { - write(decompressGzip(FileSystem.SYSTEM.source(file).buffer().readByteArray())) + write(decompressGzip(readFile(file).buffer().readByteArray())) } } diff --git a/ksoup/src/jvmMain/kotlin/com/fleeksoft/ksoup/Platform.jvm.kt b/ksoup/src/jvmMain/kotlin/com/fleeksoft/ksoup/Platform.jvm.kt index f55caee3..081fc578 100644 --- a/ksoup/src/jvmMain/kotlin/com/fleeksoft/ksoup/Platform.jvm.kt +++ b/ksoup/src/jvmMain/kotlin/com/fleeksoft/ksoup/Platform.jvm.kt @@ -7,7 +7,7 @@ import okio.Path import okio.buffer internal actual fun readGzipFile(file: Path): BufferedSource { - val fileSource = FileSystem.SYSTEM.source(file) + val fileSource = readFile(file) return GzipSource(source = fileSource).buffer() } From 28cc374bd8fbeae40e239e0a6ebe6505280fad7c Mon Sep 17 00:00:00 2001 From: sabeeh Date: Fri, 24 Nov 2023 01:49:43 +0400 Subject: [PATCH 05/10] issue #3 fix test --- .../com/fleeksoft/ksoup/KsoupNetworkTest.kt | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 ksoup-network/src/commonTest/kotlin/com/fleeksoft/ksoup/KsoupNetworkTest.kt diff --git a/ksoup-network/src/commonTest/kotlin/com/fleeksoft/ksoup/KsoupNetworkTest.kt b/ksoup-network/src/commonTest/kotlin/com/fleeksoft/ksoup/KsoupNetworkTest.kt new file mode 100644 index 00000000..5ae764fa --- /dev/null +++ b/ksoup-network/src/commonTest/kotlin/com/fleeksoft/ksoup/KsoupNetworkTest.kt @@ -0,0 +1,30 @@ +package com.fleeksoft.ksoup + +import com.fleeksoft.ksoup.network.parseGetRequest +import kotlin.test.Ignore +import kotlin.test.Test +import kotlin.test.assertNotEquals +import kotlin.test.assertTrue + +class KsoupNetworkTest { + + private val rootUri = "https://aip.dfs.de/BasicVFR/" + + // issue #3 fix + @Ignore + @Test + fun issue3RedirectLocationTest() { +// val doc = Jsoup.connect(rootUri).get() + val doc = Ksoup.parseGetRequest(rootUri) + + println("doc: ${doc.title()}") + val location = doc.location()!! + println("location: '$rootUri' --> '$location'") + // The output should be "location: 'https://aip.dfs.de/BasicVFR/' --> 'https://aip.dfs.de/BasicVFR/2023NOV16/chapter/daf49d0cf52a85f8ae58cc4f2aed1580.html'" + + assertNotEquals(rootUri, location, "resolveCurrentLink-1") + assertTrue(location.startsWith("https://aip.dfs.de/BasicVFR/20"), "resolveCurrentLink-2") + assertTrue(location.contains("/chapter/"), "resolveCurrentLink-3") + } + +} \ No newline at end of file From 48e098a4b3af3c395838f48be18002a460031f0c Mon Sep 17 00:00:00 2001 From: sabeeh Date: Fri, 24 Nov 2023 01:51:13 +0400 Subject: [PATCH 06/10] deploy.yml updated --- .github/workflows/deploy.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9e00207c..f21941d4 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -16,9 +16,8 @@ jobs: matrix: config: [ { target: android, os: ubuntu-latest, tasks: testDebugUnitTest, continueOnError: false }, -# { target: apple, os: macos-latest, tasks: iosX64Test iosSimulatorArm64Test macosX64Test macosArm64Test, continueOnError: true }, - # { target: windows, os: windows-latest, tasks: windowsTest, continueOnError: true }, # https://github.com/square/okio/issues/951 - # { target: linux, os: ubuntu-latest, tasks: linuxTest, continueOnError: false }, +# { target: apple, os: macos-latest, tasks: iosX64Test iosSimulatorArm64Test, continueOnError: true }, +# { target: linux, os: ubuntu-latest, tasks: linuxTest, continueOnError: false }, { target: desktop, os: ubuntu-latest, tasks: jvmTest, continueOnError: false }, ] runs-on: ${{ matrix.config.os }} From 94a590d2fa42c7b1ca1cbce30658a400992b6c29 Mon Sep 17 00:00:00 2001 From: sabeeh Date: Fri, 24 Nov 2023 02:15:57 +0400 Subject: [PATCH 07/10] deploy updated --- .github/workflows/deploy.yml | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f21941d4..da874564 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,19 +1,19 @@ name: Build -on: - push: +on: + push: branches: [ "main" ] - pull_request: + pull_request: branches: [ "main" ] -permissions: +permissions: contents: read pages: write -jobs: - build: - strategy: - matrix: +jobs: + build: + strategy: + matrix: config: [ { target: android, os: ubuntu-latest, tasks: testDebugUnitTest, continueOnError: false }, # { target: apple, os: macos-latest, tasks: iosX64Test iosSimulatorArm64Test, continueOnError: true }, @@ -22,11 +22,11 @@ jobs: ] runs-on: ${{ matrix.config.os }} name: Build ${{ matrix.config.target }} - steps: + steps: - uses: actions/checkout@v3 - name: Setup JDK 17 uses: actions/setup-java@v3 - with: + with: java-version: '17' distribution: 'temurin' @@ -37,21 +37,21 @@ jobs: continue-on-error: ${{ matrix.config.continueOnError }} run: ./gradlew ${{ matrix.config.tasks }} - release: + release: if: ${{ github.event_name != 'pull_request' }} runs-on: macos-latest - needs: + needs: - build - environment: + environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} - steps: + steps: - uses: actions/checkout@v3 - name: Setup JDK 17 uses: actions/setup-java@v3 - with: + with: java-version: '17' distribution: 'temurin' @@ -68,7 +68,7 @@ jobs: echo mavenCentralUsername="${SONATYPE_PASSWORD}" >> "local.properties" echo gpgKeyPassword="${GPG_KEY_PASSWORD}" >> "local.properties" echo gpgKeySecret="${GPG_KEY_SECRET}" >> "local.properties" - env: + env: SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} GPG_KEY_PASSWORD: ${{ secrets.GPG_KEY_PASSWORD }} @@ -82,7 +82,7 @@ jobs: - name: Upload artifact uses: actions/upload-pages-artifact@v1 - with: + with: path: ${{ github.workspace }}/build/dokka/htmlMultiModule - name: Release to GitHub Pages From 3ff03cc0cf39fbbcce3bfa404b0eff987693f9d0 Mon Sep 17 00:00:00 2001 From: sabeeh Date: Fri, 24 Nov 2023 02:40:56 +0400 Subject: [PATCH 08/10] code optimize and cleanup --- .../fleeksoft/ksoup/network/KsoupNetwork.kt | 4 +- .../fleeksoft/ksoup/internal/StringUtil.kt | 12 ++-- .../com/fleeksoft/ksoup/nodes/Element.kt | 65 +++++++++---------- .../com/fleeksoft/ksoup/nodes/LeafNode.kt | 26 ++++---- .../kotlin/com/fleeksoft/ksoup/nodes/Node.kt | 17 +++-- .../kotlin/com/fleeksoft/ksoup/nodes/Range.kt | 16 ++--- .../com/fleeksoft/ksoup/nodes/TextNode.kt | 4 +- .../fleeksoft/ksoup/parser/CharacterReader.kt | 6 +- .../ksoup/parser/HtmlTreeBuilderState.kt | 42 +++++------- .../fleeksoft/ksoup/parser/ParseSettings.kt | 14 ++-- .../kotlin/com/fleeksoft/ksoup/parser/Tag.kt | 15 ++--- .../com/fleeksoft/ksoup/parser/Token.kt | 12 ++-- .../com/fleeksoft/ksoup/select/Collector.kt | 20 +++--- .../ksoup/select/CombiningEvaluator.kt | 6 +- .../com/fleeksoft/ksoup/select/Evaluator.kt | 18 ++--- .../fleeksoft/ksoup/parser/HtmlParserTest.kt | 4 +- .../fleeksoft/ksoup/parser/TokeniserTest.kt | 4 +- .../fleeksoft/ksoup/select/QueryParserTest.kt | 19 +++--- .../fleeksoft/ksoup/select/SelectorTest.kt | 2 +- .../kotlin/com/fleeksoft/ksoup/Test.ios.kt | 52 --------------- 20 files changed, 138 insertions(+), 220 deletions(-) delete mode 100644 ksoup/src/iosTest/kotlin/com/fleeksoft/ksoup/Test.ios.kt diff --git a/ksoup-network/src/commonMain/kotlin/com/fleeksoft/ksoup/network/KsoupNetwork.kt b/ksoup-network/src/commonMain/kotlin/com/fleeksoft/ksoup/network/KsoupNetwork.kt index f31fb837..50e45549 100644 --- a/ksoup-network/src/commonMain/kotlin/com/fleeksoft/ksoup/network/KsoupNetwork.kt +++ b/ksoup-network/src/commonMain/kotlin/com/fleeksoft/ksoup/network/KsoupNetwork.kt @@ -50,7 +50,7 @@ public fun Ksoup.parseSubmitRequest( httpRequestBuilder: HttpRequestBuilder.() -> Unit = {}, parser: Parser = Parser.htmlParser(), ): Document { - var finalUrl = url + var finalUrl: String = url val result: String = runBlocking { val httpResponse = NetworkHelper.instance.submitForm( @@ -82,7 +82,7 @@ public fun Ksoup.parsePostRequest( httpRequestBuilder: HttpRequestBuilder.() -> Unit = {}, parser: Parser = Parser.htmlParser(), ): Document { - var finalUrl = url + var finalUrl: String = url val result: String = runBlocking { val httpResponse = NetworkHelper.instance.post( diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/internal/StringUtil.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/internal/StringUtil.kt index 6c19f208..9c1ccf8d 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/internal/StringUtil.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/internal/StringUtil.kt @@ -308,14 +308,14 @@ internal object StringUtil { // TODO: replace this fun releaseBuilder(sb: StringBuilder): String { - var sb: StringBuilder = sb - val string: String = sb.toString() - if (sb.length > MaxCachedBuilderSize) { - sb = StringBuilder(MaxCachedBuilderSize) // make sure it hasn't grown too big + var stringBuilder: StringBuilder = sb + val string: String = stringBuilder.toString() + if (stringBuilder.length > MaxCachedBuilderSize) { + stringBuilder = StringBuilder(MaxCachedBuilderSize) // make sure it hasn't grown too big } else { - sb.clear() // make sure it's emptied on release + stringBuilder.clear() // make sure it's emptied on release } - stringLocalBuilders.addLast(sb) + stringLocalBuilders.addLast(stringBuilder) while (stringLocalBuilders.size > MaxIdleBuilders) { stringLocalBuilders.removeLast() } diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Element.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Element.kt index 02ec6496..628e30a6 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Element.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Element.kt @@ -601,12 +601,12 @@ public open class Element : Node { * @return this element, for chaining. */ public fun insertChildren(index: Int, children: Collection): Element { - var index = index + var calculatedIndex = index val currentSize = childNodeSize() - if (index < 0) index += currentSize + 1 // roll around - Validate.isTrue(index in 0..currentSize, "Insert position out of bounds.") + if (calculatedIndex < 0) calculatedIndex += currentSize + 1 // roll around + Validate.isTrue(calculatedIndex in 0..currentSize, "Insert position out of bounds.") val nodeArray: Array = children.toTypedArray() - addChildren(index, *nodeArray) + addChildren(calculatedIndex, *nodeArray) return this } @@ -620,11 +620,11 @@ public open class Element : Node { * @return this element, for chaining. */ public fun insertChildren(index: Int, vararg children: Node): Element { - var index = index + var calculatedIndex = index val currentSize = childNodeSize() - if (index < 0) index += currentSize + 1 // roll around - Validate.isTrue(index in 0..currentSize, "Insert position out of bounds.") - addChildren(index, *children) + if (calculatedIndex < 0) calculatedIndex += currentSize + 1 // roll around + Validate.isTrue(calculatedIndex in 0..currentSize, "Insert position out of bounds.") + addChildren(calculatedIndex, *children) return this } @@ -804,7 +804,7 @@ public open class Element : Node { val doc: Document? = ownerDocument() if (doc != null) { val els: Elements = doc.select(idSel) - if (els.size === 1 && els[0] === this) { + if (els.size == 1 && els[0] === this) { // otherwise, continue to the nth-child impl return idSel } @@ -997,10 +997,9 @@ public open class Element : Node { * @return a matching unmodifiable list of elements. Will be empty if this element and none of its children match. */ public fun getElementsByTag(tagName: String?): Elements { - var tagName = tagName Validate.notEmpty(tagName) - tagName = normalize(tagName) - return Collector.collect(Evaluator.Tag(tagName), this) + val normalizedTagName = normalize(tagName) + return Collector.collect(Evaluator.Tag(normalizedTagName), this) } /** @@ -1044,10 +1043,9 @@ public open class Element : Node { * @return elements that have this attribute, empty if none */ public fun getElementsByAttribute(key: String): Elements { - var key = key Validate.notEmpty(key) - key = key.trim { it <= ' ' } - return Collector.collect(Evaluator.Attribute(key), this) + val trimmedKey = key.trim { it <= ' ' } + return Collector.collect(Evaluator.Attribute(trimmedKey), this) } /** @@ -1057,10 +1055,9 @@ public open class Element : Node { * @return elements that have attribute names that start with the prefix, empty if none. */ public fun getElementsByAttributeStarting(keyPrefix: String): Elements { - var keyPrefix = keyPrefix Validate.notEmpty(keyPrefix) - keyPrefix = keyPrefix.trim { it <= ' ' } - return Collector.collect(Evaluator.AttributeStarting(keyPrefix), this) + val trimmedKeyPrefix = keyPrefix.trim { it <= ' ' } + return Collector.collect(Evaluator.AttributeStarting(trimmedKeyPrefix), this) } /** @@ -1427,27 +1424,23 @@ public open class Element : Node { */ public fun data(): String { val sb: StringBuilder = StringUtil.borrowBuilder() - traverse( - object : NodeVisitor { - override fun head(childNode: Node, depth: Int) { - when (childNode) { - is DataNode -> { - sb.append(childNode.getWholeData()) - } + traverse { childNode, depth -> + when (childNode) { + is DataNode -> { + sb.append(childNode.getWholeData()) + } - is Comment -> { - sb.append(childNode.getData()) - } + is Comment -> { + sb.append(childNode.getData()) + } - is CDataNode -> { - // this shouldn't really happen because the html parser won't see the cdata as anything special when parsing script. - // but in case another type gets through. - sb.append(childNode.getWholeText()) - } - } + is CDataNode -> { + // this shouldn't really happen because the html parser won't see the cdata as anything special when parsing script. + // but in case another type gets through. + sb.append(childNode.getWholeText()) } - }, - ) + } + } return StringUtil.releaseBuilder(sb) } diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/LeafNode.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/LeafNode.kt index bf977f7b..6d30913e 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/LeafNode.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/LeafNode.kt @@ -30,37 +30,37 @@ public abstract class LeafNode : Node() { attr(nodeName(), value) } - override fun attr(key: String): String { + override fun attr(attributeKey: String): String { return if (!hasAttributes()) { - if (nodeName() == key) value as String else EmptyString + if (nodeName() == attributeKey) value as String else EmptyString } else { - super.attr(key) + super.attr(attributeKey) } } - override fun attr(key: String, value: String?): Node { - if (!hasAttributes() && key == nodeName()) { - this.value = value + override fun attr(attributeKey: String, attributeValue: String?): Node { + if (!hasAttributes() && attributeKey == nodeName()) { + this.value = attributeValue } else { ensureAttributes() - super.attr(key, value) + super.attr(attributeKey, attributeValue) } return this } - override fun hasAttr(key: String): Boolean { + override fun hasAttr(attributeKey: String): Boolean { ensureAttributes() - return super.hasAttr(key) + return super.hasAttr(attributeKey) } - override fun removeAttr(key: String): Node { + override fun removeAttr(attributeKey: String): Node { ensureAttributes() - return super.removeAttr(key) + return super.removeAttr(attributeKey) } - override fun absUrl(key: String): String { + override fun absUrl(attributeKey: String): String { ensureAttributes() - return super.absUrl(key) + return super.absUrl(attributeKey) } override fun baseUri(): String { diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Node.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Node.kt index 460de4d8..c874f4c3 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Node.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Node.kt @@ -109,9 +109,8 @@ public abstract class Node protected constructor() : Cloneable { * @return this (for chaining) */ public open fun attr(attributeKey: String, attributeValue: String?): Node { - var attributeKey = attributeKey - attributeKey = NodeUtils.parser(this)!!.settings()!!.normalizeAttribute(attributeKey) - attributes().putIgnoreCase(attributeKey, attributeValue) + val normalizedAttributeKey = NodeUtils.parser(this).settings()!!.normalizeAttribute(attributeKey) + attributes().putIgnoreCase(normalizedAttributeKey, attributeValue) return this } @@ -365,7 +364,7 @@ public abstract class Node protected constructor() : Cloneable { private fun addSiblingHtml(index: Int, html: String) { Validate.notNull(_parentNode) val context: Element? = if (parent() is Element) parent() as Element? else null - val nodes: List = NodeUtils.parser(this)!! + val nodes: List = NodeUtils.parser(this) .parseFragmentInput(html, context, baseUri()) _parentNode!!.addChildren(index, *nodes.toTypedArray()) } @@ -383,7 +382,7 @@ public abstract class Node protected constructor() : Cloneable { // Parse context - parent (because wrapping), this, or null val context: Element = if (_parentNode != null && _parentNode is Element) _parentNode as Element else (if (this is Element) this else null)!! - val wrapChildren: List = NodeUtils.parser(this)!! + val wrapChildren: List = NodeUtils.parser(this) .parseFragmentInput(html, context, baseUri()) val wrapNode = wrapChildren[0] as? Element // nothing to wrap with; noop ?: return this @@ -432,13 +431,13 @@ public abstract class Node protected constructor() : Cloneable { } private fun getDeepChild(el: Element): Element { - var el: Element = el - var child: Element? = el.firstElementChild() + var resultEl: Element = el + var child: Element? = resultEl.firstElementChild() while (child != null) { - el = child + resultEl = child child = child.firstElementChild() } - return el + return resultEl } internal open fun nodelistChanged() { diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Range.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Range.kt index bf762210..09cb0112 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Range.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Range.kt @@ -42,10 +42,10 @@ internal class Range node.attributes().putUserData(if (start) RangeKey else EndRangeKey, this) } - override fun equals(o: Any?): Boolean { - if (this === o) return true - if (o == null || this::class != o::class) return false - val range = o as Range + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + val range = other as Range return if (start != range.start) false else end == range.end } @@ -117,10 +117,10 @@ internal class Range return "$lineNumber,$columnNumber:$pos" } - override fun equals(o: Any?): Boolean { - if (this === o) return true - if (o == null || this::class != o::class) return false - val position = o as Position + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + val position = other as Position if (pos != position.pos) return false return if (lineNumber != position.lineNumber) false else columnNumber == position.columnNumber } diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/TextNode.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/TextNode.kt index 35b1cf8e..68d76858 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/TextNode.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/TextNode.kt @@ -137,9 +137,7 @@ public open class TextNode(text: String) : LeafNode() { } internal fun normaliseWhitespace(text: String): String { - var text = text - text = StringUtil.normaliseWhitespace(text) - return text + return StringUtil.normaliseWhitespace(text) } internal fun stripLeadingWhitespace(text: String): String { diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/CharacterReader.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/CharacterReader.kt index 27f067d3..acb27bb5 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/CharacterReader.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/CharacterReader.kt @@ -769,11 +769,11 @@ internal class CharacterReader { * Check if the value of the provided range equals the string. */ fun rangeEquals(charBuf: CharArray?, start: Int, count: Int, cached: String): Boolean { - var count = count - if (count == cached.length) { + var loopCount = count + if (loopCount == cached.length) { var i = start var j = 0 - while (count-- != 0) { + while (loopCount-- != 0) { if (charBuf!![i++] != cached[j++]) return false } return true diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/HtmlTreeBuilderState.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/HtmlTreeBuilderState.kt index d097dc5a..6de362c9 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/HtmlTreeBuilderState.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/HtmlTreeBuilderState.kt @@ -7,16 +7,6 @@ import com.fleeksoft.ksoup.nodes.Attributes import com.fleeksoft.ksoup.nodes.Document import com.fleeksoft.ksoup.nodes.DocumentType import com.fleeksoft.ksoup.nodes.Element -import com.fleeksoft.ksoup.parser.HtmlTreeBuilderState.Constants.AfterHeadBody -import com.fleeksoft.ksoup.parser.HtmlTreeBuilderState.Constants.BeforeHtmlToHead -import com.fleeksoft.ksoup.parser.HtmlTreeBuilderState.Constants.InBodyEndOtherErrors -import com.fleeksoft.ksoup.parser.HtmlTreeBuilderState.Constants.InBodyStartToHead -import com.fleeksoft.ksoup.parser.HtmlTreeBuilderState.Constants.InHeadEmpty -import com.fleeksoft.ksoup.parser.HtmlTreeBuilderState.Constants.InHeadNoScriptHead -import com.fleeksoft.ksoup.parser.HtmlTreeBuilderState.Constants.InHeadNoscriptIgnore -import com.fleeksoft.ksoup.parser.HtmlTreeBuilderState.Constants.InHeadRaw -import com.fleeksoft.ksoup.parser.HtmlTreeBuilderState.Constants.InTableFoster -import com.fleeksoft.ksoup.parser.HtmlTreeBuilderState.Constants.InTableToBody /** * The Tree Builder's current state. Each state embodies the processing for the state, and transitions to other states. @@ -62,7 +52,7 @@ internal enum class HtmlTreeBuilderState { } else if (t.isStartTag() && t.asStartTag().normalName().equals("html")) { tb.insert(t.asStartTag()) tb.transition(BeforeHead) - } else if (t.isEndTag() && inSorted(t.asEndTag().normalName(), BeforeHtmlToHead)) { + } else if (t.isEndTag() && inSorted(t.asEndTag().normalName(), Constants.BeforeHtmlToHead)) { return anythingElse(t, tb) } else if (t.isEndTag()) { tb.error(this) @@ -94,7 +84,7 @@ internal enum class HtmlTreeBuilderState { val head: Element = tb.insert(t.asStartTag()) tb.setHeadElement(head) tb.transition(InHead) - } else if (t.isEndTag() && inSorted(t.asEndTag().normalName(), BeforeHtmlToHead)) { + } else if (t.isEndTag() && inSorted(t.asEndTag().normalName(), Constants.BeforeHtmlToHead)) { tb.processStartTag("head") return tb.process(t) } else if (t.isEndTag()) { @@ -125,7 +115,7 @@ internal enum class HtmlTreeBuilderState { var name: String = start.normalName() if (name == "html") { return InBody.process(t, tb) - } else if (inSorted(name, InHeadEmpty)) { + } else if (inSorted(name, Constants.InHeadEmpty)) { val el: Element = tb.insertEmpty(start) // com.fleeksoft.ksoup special: update base the first time it is seen if (name == "base" && el.hasAttr("href")) tb.maybeSetBaseUri(el) @@ -134,7 +124,7 @@ internal enum class HtmlTreeBuilderState { // todo: charset switches } else if (name == "title") { handleRcData(start, tb) - } else if (inSorted(name, InHeadRaw)) { + } else if (inSorted(name, Constants.InHeadRaw)) { handleRawtext(start, tb) } else if (name == "noscript") { // else if noscript && scripting flag = true: rawtext (com.fleeksoft.ksoup doesn't run script, to handle as noscript) @@ -206,7 +196,7 @@ internal enum class HtmlTreeBuilderState { tb.transition(InHead) } else if (isWhitespace(t) || t.isComment() || t.isStartTag() && inSorted( t.asStartTag().normalName(), - InHeadNoScriptHead, + Constants.InHeadNoScriptHead, ) ) { return tb.process(t, InHead) @@ -214,7 +204,7 @@ internal enum class HtmlTreeBuilderState { return anythingElse(t, tb) } else if (t.isStartTag() && inSorted( t.asStartTag().normalName(), - InHeadNoscriptIgnore, + Constants.InHeadNoscriptIgnore, ) || t.isEndTag() ) { tb.error(this) @@ -254,7 +244,7 @@ internal enum class HtmlTreeBuilderState { } else if (name == "frameset") { tb.insert(startTag) tb.transition(InFrameset) - } else if (inSorted(name, InBodyStartToHead)) { + } else if (inSorted(name, Constants.InBodyStartToHead)) { tb.error(this) val head: Element = tb.getHeadElement()!! tb.push(head) @@ -268,7 +258,7 @@ internal enum class HtmlTreeBuilderState { } } else if (t.isEndTag()) { val name: String = t.asEndTag().normalName() - if (inSorted(name, AfterHeadBody)) { + if (inSorted(name, Constants.AfterHeadBody)) { anythingElse(t, tb) } else if (name == "template") { tb.process(t, InHead) @@ -320,7 +310,7 @@ internal enum class HtmlTreeBuilderState { Token.TokenType.EndTag -> return inBodyEndTag(t, tb) Token.TokenType.EOF -> { if (tb.templateModeSize() > 0) return tb.process(t, InTemplate) - if (tb.onStackNot(InBodyEndOtherErrors)) tb.error(this) + if (tb.onStackNot(Constants.InBodyEndOtherErrors)) tb.error(this) } } return true @@ -389,7 +379,7 @@ internal enum class HtmlTreeBuilderState { val html: Element = tb.stack[0]!! if (startTag.hasAttributes()) { for (attribute in (startTag.attributes ?: emptyList())) { - if (!html.hasAttr(attribute!!.key)) { + if (!html.hasAttr(attribute.key)) { html.attributes() .put(attribute) } @@ -433,7 +423,7 @@ internal enum class HtmlTreeBuilderState { return false // ignore frameset } else { val second: Element? = stack[1] - if (second?.parent() != null) second?.remove() + if (second?.parent() != null) second.remove() // pop up to html element while (stack.size > 1) stack.removeAt(stack.size - 1) tb.insert(startTag) @@ -745,7 +735,7 @@ internal enum class HtmlTreeBuilderState { tb.error(this) return false } else { - if (tb.onStackNot(InBodyEndOtherErrors)) tb.error(this) + if (tb.onStackNot(Constants.InBodyEndOtherErrors)) tb.error(this) tb.transition(AfterBody) } @@ -753,7 +743,7 @@ internal enum class HtmlTreeBuilderState { tb.error(this) false // ignore } else { - if (tb.onStackNot(InBodyEndOtherErrors)) tb.error(this) + if (tb.onStackNot(Constants.InBodyEndOtherErrors)) tb.error(this) tb.transition(AfterBody) tb.process(t) // re-process } @@ -989,7 +979,7 @@ internal enum class HtmlTreeBuilderState { }, InTable { override fun process(t: Token, tb: HtmlTreeBuilder): Boolean { - if (t.isCharacter() && inSorted(tb.currentElement().normalName(), InTableFoster)) { + if (t.isCharacter() && inSorted(tb.currentElement().normalName(), Constants.InTableFoster)) { tb.resetPendingTableCharacters() tb.markInsertionMode() tb.transition(InTableText) @@ -1118,7 +1108,7 @@ internal enum class HtmlTreeBuilderState { if (!isWhitespace(c)) { // InTable anything else section: tb.error(this) - if (inSorted(tb.currentElement().normalName(), InTableFoster)) { + if (inSorted(tb.currentElement().normalName(), Constants.InTableFoster)) { tb.isFosterInserts = true tb.process(c, InBody) tb.isFosterInserts = false @@ -1343,7 +1333,7 @@ internal enum class HtmlTreeBuilderState { tb.pop() // tr tb.transition(InTableBody) return tb.process(t) - } else if (inSorted(name, InTableToBody)) { // "tbody", "tfoot", "thead" + } else if (inSorted(name, Constants.InTableToBody)) { // "tbody", "tfoot", "thead" if (!tb.inTableScope(name)) { tb.error(this) return false diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/ParseSettings.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/ParseSettings.kt index 6eea18ff..205e56bd 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/ParseSettings.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/ParseSettings.kt @@ -35,20 +35,18 @@ public class ParseSettings * Normalizes a tag name according to the case preservation setting. */ public fun normalizeTag(name: String): String { - var name = name - name = name.trim { it <= ' ' } - if (!preserveTagCase) name = lowerCase(name) - return name + var trimmedName = name.trim { it <= ' ' } + if (!preserveTagCase) trimmedName = lowerCase(trimmedName) + return trimmedName } /** * Normalizes an attribute according to the case preservation setting. */ public fun normalizeAttribute(name: String): String { - var name = name - name = name.trim { it <= ' ' } - if (!preserveAttributeCase) name = lowerCase(name) - return name + var trimmedName = name.trim { it <= ' ' } + if (!preserveAttributeCase) trimmedName = lowerCase(trimmedName) + return trimmedName } diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/Tag.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/Tag.kt index 98e1783e..fcca7125 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/Tag.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/Tag.kt @@ -153,26 +153,25 @@ public data class Tag( namespace: String = Parser.NamespaceHtml, settings: ParseSettings? = ParseSettings.preserveCase, ): Tag { - var tagName = tagName Validate.notEmpty(tagName) var tag = Tags[tagName] if (tag != null && tag.namespace == namespace) return tag - tagName = settings!!.normalizeTag(tagName) // the name we'll use - Validate.notEmpty(tagName) + val normalizedTagName = settings!!.normalizeTag(tagName) // the name we'll use + Validate.notEmpty(normalizedTagName) val normalName: String = - Normalizer.lowerCase(tagName) // the lower-case name to get tag settings off + Normalizer.lowerCase(normalizedTagName) // the lower-case name to get tag settings off tag = Tags[normalName] if (tag != null && tag.namespace == namespace) { - if (settings!!.preserveTagCase() && tagName != normalName) { + if (settings.preserveTagCase() && normalizedTagName != normalName) { tag = tag.clone() // get a new version vs the static one, so name update doesn't reset all - tag.name = tagName + tag.name = normalizedTagName } return tag } // not defined: create default; go anywhere, do anything! (incl be inside a

) - tag = Tag(tagName, namespace) + tag = Tag(normalizedTagName, namespace) tag.isBlock = false return tag } @@ -189,7 +188,7 @@ public data class Tag( * @return The tag, either defined or new generic. * @see .valueOf */ - public fun valueOf(tagName: String, settings: ParseSettings?): Tag? { + public fun valueOf(tagName: String, settings: ParseSettings?): Tag { return valueOf(tagName, Parser.NamespaceHtml, settings) } diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/Token.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/Token.kt index 2cb891e7..5d23a6db 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/Token.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/parser/Token.kt @@ -187,9 +187,8 @@ internal abstract class Token private constructor() { // these appenders are rarely hit in not null state-- caused by null chars. fun appendTagName(append: String) { // might have null chars - need to replace with null replacement character - var append = append - append = append.replace(TokeniserState.nullChar, Tokeniser.replacementChar) - tagName = if (tagName == null) append else tagName + append + val replacedAppend = append.replace(TokeniserState.nullChar, Tokeniser.replacementChar) + tagName = if (tagName == null) replacedAppend else tagName + replacedAppend normalName = ParseSettings.normalName(tagName) } @@ -199,13 +198,12 @@ internal abstract class Token private constructor() { fun appendAttributeName(append: String) { // might have null chars because we eat in one pass - need to replace with null replacement character - var append = append - append = append.replace(TokeniserState.nullChar, Tokeniser.replacementChar) + val replacedAppend = append.replace(TokeniserState.nullChar, Tokeniser.replacementChar) ensureAttrName() if (attrName.isEmpty()) { - attrNameS = append + attrNameS = replacedAppend } else { - attrName.append(append) + attrName.append(replacedAppend) } } diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/Collector.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/Collector.kt index d73a02b5..34fbb80e 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/Collector.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/Collector.kt @@ -21,12 +21,10 @@ internal object Collector { eval.reset() val elements = Elements() NodeTraversor.traverse( - object : NodeVisitor { - override fun head(node: Node, depth: Int) { - if (node is Element) { - val el: Element = node - if (eval.matches(root, el)) elements.add(el) - } + { node, depth -> + if (node is Element) { + val el: Element = node + if (eval.matches(root, el)) elements.add(el) } }, root, @@ -41,7 +39,7 @@ internal object Collector { * @param root root of tree to descend * @return the first match; `null` if none */ - + fun findFirst(eval: Evaluator, root: Element): Element? { eval.reset() val finder = FirstFinder(eval) @@ -49,10 +47,10 @@ internal object Collector { } internal class FirstFinder(eval: Evaluator) : NodeFilter { - + private var evalRoot: Element? = null - + private var match: Element? = null private val eval: Evaluator @@ -60,7 +58,7 @@ internal object Collector { this.eval = eval } - + fun find(root: Element?, start: Element): Element? { evalRoot = root match = null @@ -70,7 +68,7 @@ internal object Collector { override fun head(node: Node, depth: Int): NodeFilter.FilterResult { if (node is Element) { - val el: Element = node as Element + val el: Element = node if (eval.matches(evalRoot!!, el)) { match = el return STOP diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/CombiningEvaluator.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/CombiningEvaluator.kt index ec4578cc..4f43845a 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/CombiningEvaluator.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/CombiningEvaluator.kt @@ -29,7 +29,7 @@ internal abstract class CombiningEvaluator internal constructor() : Evaluator() return cost } - + fun rightMostEvaluator(): Evaluator? { return if (num > 0) evaluators[num - 1] else null } @@ -94,10 +94,10 @@ internal abstract class CombiningEvaluator internal constructor() : Evaluator() updateEvaluators() } - override fun matches(root: Element, node: Element): Boolean { + override fun matches(root: Element, element: Element): Boolean { for (i in 0 until num) { val s: Evaluator = sortedEvaluators[i] - if (s.matches(root, node)) return true + if (s.matches(root, element)) return true } return false } diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/Evaluator.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/Evaluator.kt index 1b515b9b..009536f4 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/Evaluator.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/Evaluator.kt @@ -276,18 +276,18 @@ internal abstract class Evaluator protected constructor() { var value: String init { - var value = value + var resultValue = value Validate.notEmpty(key) - Validate.notEmpty(value) + Validate.notEmpty(resultValue) this.key = normalize(key) val isStringLiteral = ( - value.startsWith("'") && value.endsWith("'") || - value.startsWith("\"") && value.endsWith("\"") + resultValue.startsWith("'") && resultValue.endsWith("'") || + resultValue.startsWith("\"") && resultValue.endsWith("\"") ) if (isStringLiteral) { - value = value.substring(1, value.length - 1) + resultValue = resultValue.substring(1, resultValue.length - 1) } - this.value = if (trimValue) normalize(value) else normalize(value, isStringLiteral) + this.value = if (trimValue) normalize(resultValue) else normalize(resultValue, isStringLiteral) } } @@ -339,7 +339,7 @@ internal abstract class Evaluator protected constructor() { */ class IndexEquals(index: Int) : IndexEvaluator(index) { override fun matches(root: Element, element: Element): Boolean { - return element.elementSiblingIndex() === index + return element.elementSiblingIndex() == index } override fun toString(): String { @@ -450,7 +450,7 @@ internal abstract class Evaluator protected constructor() { open class IsNthLastOfType(a: Int, b: Int) : CssNthEvaluator(a, b) { override fun calculatePosition(root: Element, element: Element): Int { - val parent: Element = element.parent() ?: return 0 + element.parent() ?: return 0 var pos = 0 var next: Element? = element while (next != null) { @@ -530,7 +530,7 @@ internal abstract class Evaluator protected constructor() { override fun matches(root: Element, element: Element): Boolean { val family: List = element.childNodes() for (n in family) { - if (n is TextNode) return (n as TextNode).isBlank() + if (n is TextNode) return n.isBlank() if (!(n is Comment || n is XmlDeclaration || n is DocumentType)) return false } return true diff --git a/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/parser/HtmlParserTest.kt b/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/parser/HtmlParserTest.kt index fabc7a10..83e86871 100644 --- a/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/parser/HtmlParserTest.kt +++ b/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/parser/HtmlParserTest.kt @@ -1793,7 +1793,7 @@ class HtmlParserTest { val doc = Ksoup.parse(html) val div = doc.selectFirst("div") assertNotNull(div) - assertEquals("\nOne\nTwo Three\nFour", div!!.wholeText()) + assertEquals("\nOne\nTwo Three\nFour", div.wholeText()) assertEquals("\nOne\nTwo ", div.wholeOwnText()) } @@ -1917,7 +1917,7 @@ class HtmlParserTest { val tmplRow = doc.selectFirst("template#2") assertNotNull(tmplRow) assertNotNull(tmplTbl) - tmplRow!!.appendChild(tmplRow.clone()) + tmplRow.appendChild(tmplRow.clone()) doc.select("template").unwrap() want = "
OneTwoOneTwo
" diff --git a/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/parser/TokeniserTest.kt b/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/parser/TokeniserTest.kt index 893fc1c6..0f2e4107 100644 --- a/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/parser/TokeniserTest.kt +++ b/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/parser/TokeniserTest.kt @@ -185,7 +185,7 @@ class TokeniserTest { val doc = parser.parseInput(testMarkup, "") val commentNode = doc.body().childNode(0) assertTrue(commentNode is Comment, "Expected comment node") - assertEquals(expectedCommentData, (commentNode as Comment).getData()) + assertEquals(expectedCommentData, commentNode.getData()) } @Test @@ -202,6 +202,6 @@ class TokeniserTest { val doc = parser.parseInput(testMarkup, "") val cdataNode = doc.body().childNode(0) assertTrue(cdataNode is CDataNode, "Expected CDATA node") - assertEquals(cdataContents, (cdataNode as CDataNode).text()) + assertEquals(cdataContents, cdataNode.text()) } } diff --git a/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/select/QueryParserTest.kt b/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/select/QueryParserTest.kt index c3904798..bc0662dc 100644 --- a/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/select/QueryParserTest.kt +++ b/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/select/QueryParserTest.kt @@ -48,14 +48,12 @@ class QueryParserTest { // top level or, three child ands val eval = QueryParser.parse("a b, c d, e f") assertTrue(eval is CombiningEvaluator.Or) - val or = eval as CombiningEvaluator.Or - assertEquals(3, or.evaluators.size) - for (innerEval in or.evaluators) { + assertEquals(3, eval.evaluators.size) + for (innerEval in eval.evaluators) { assertTrue(innerEval is CombiningEvaluator.And) - val and = innerEval as CombiningEvaluator.And - assertEquals(2, and.evaluators.size) - assertTrue(and.evaluators[0] is StructuralEvaluator.Parent) - assertTrue(and.evaluators[1] is Evaluator.Tag) + assertEquals(2, innerEval.evaluators.size) + assertTrue(innerEval.evaluators[0] is StructuralEvaluator.Parent) + assertTrue(innerEval.evaluators[1] is Evaluator.Tag) } } @@ -64,10 +62,9 @@ class QueryParserTest { val query = ".foo.qux > ol.bar, ol > li + li" val eval = QueryParser.parse(query) assertTrue(eval is CombiningEvaluator.Or) - val or = eval as CombiningEvaluator.Or - assertEquals(2, or.evaluators.size) - val run = or.evaluators[0] as ImmediateParentRun - val andRight = or.evaluators[1] as CombiningEvaluator.And + assertEquals(2, eval.evaluators.size) + val run = eval.evaluators[0] as ImmediateParentRun + val andRight = eval.evaluators[1] as CombiningEvaluator.And assertEquals(".foo.qux > ol.bar", run.toString()) assertEquals(2, run.evaluators.size) val runAnd = run.evaluators[0] diff --git a/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/select/SelectorTest.kt b/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/select/SelectorTest.kt index 828ef781..fa2622f4 100644 --- a/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/select/SelectorTest.kt +++ b/ksoup/src/commonTest/kotlin/com/fleeksoft/ksoup/select/SelectorTest.kt @@ -1016,7 +1016,7 @@ class SelectorTest { assertNotNull(div) // want to select One and Three only - the first level children - val spans = div!!.select(":root > span") + val spans = div.select(":root > span") assertEquals(2, spans.size) assertEquals("One Two", spans[0].text()) assertEquals("Three Four", spans[1].text()) diff --git a/ksoup/src/iosTest/kotlin/com/fleeksoft/ksoup/Test.ios.kt b/ksoup/src/iosTest/kotlin/com/fleeksoft/ksoup/Test.ios.kt deleted file mode 100644 index 3a3afa0e..00000000 --- a/ksoup/src/iosTest/kotlin/com/fleeksoft/ksoup/Test.ios.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.fleeksoft.ksoup - -import com.fleeksoft.ksoup.integration.ParseTest -import com.fleeksoft.ksoup.nodes.Attributes -import com.fleeksoft.ksoup.nodes.Document -import okio.Path -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertTrue - -class IosGreetingTest { - - @Test - fun loadsZGzipFile() { - // compressed on win, with z suffix - val `in`: String = ParseTest.getResourceAbsolutePath("htmltests/gzip.html.z") - val doc: Document = Ksoup.parseFile(`in`, null) - val title = doc.title() - assertEquals("Gzip test", title) - assertEquals("This is a gzipped HTML file.", doc.selectFirst("p")!!.text()) - } - - @Test - fun html() { - val a = Attributes() - a.put("Tot", "a&p") - a.put("Hello", "There") - a.put("data-name", "Ksoup") - assertEquals(3, a.size()) - assertTrue(a.hasKey("Tot")) - assertTrue(a.hasKey("Hello")) - assertTrue(a.hasKey("data-name")) - assertFalse(a.hasKey("tot")) - assertTrue(a.hasKeyIgnoreCase("tot")) - assertEquals("There", a.getIgnoreCase("hEllo")) - val dataset: Attributes.Dataset = a.dataset() - assertEquals(1, dataset.size) - assertEquals("Ksoup", dataset["name"]) - assertEquals("", a["tot"]) - assertEquals("a&p", a["Tot"]) - assertEquals("a&p", a.getIgnoreCase("tot")) - assertEquals(" Tot=\"a&p\" Hello=\"There\" data-name=\"Ksoup\"", a.html()) - assertEquals(a.html(), a.toString()) - } - - @Test - fun testExample() { - println("testExample running for testinng....") -// assertTrue(Greeting().greet().contains("iOS"), "Check iOS is mentioned") - } -} \ No newline at end of file From 1bf154c065cfae20822c93b8abe306be2160dbea Mon Sep 17 00:00:00 2001 From: sabeeh Date: Fri, 24 Nov 2023 02:42:54 +0400 Subject: [PATCH 09/10] code optimize and cleanup --- .../kotlin/com/fleeksoft/ksoup/nodes/Element.kt | 2 +- .../kotlin/com/fleeksoft/ksoup/select/NodeFilter.kt | 2 +- .../kotlin/com/fleeksoft/ksoup/select/QueryParser.kt | 11 +++++------ .../com/fleeksoft/ksoup/select/StructuralEvaluator.kt | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Element.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Element.kt index 628e30a6..ccad3134 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Element.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/nodes/Element.kt @@ -1614,7 +1614,7 @@ public open class Element : Node { override fun outerHtmlHead(accum: Appendable, depth: Int, out: Document.OutputSettings) { if (shouldIndent(out)) { if (accum is StringBuilder) { - if ((accum as StringBuilder).isNotEmpty()) indent(accum, depth, out) + if (accum.isNotEmpty()) indent(accum, depth, out) } else { indent(accum, depth, out) } diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/NodeFilter.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/NodeFilter.kt index 26d923d9..3f55056e 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/NodeFilter.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/NodeFilter.kt @@ -53,7 +53,7 @@ public interface NodeFilter { * @param depth the depth of the node, relative to the root node. E.g., the root node has depth 0, and a child node of that will have depth 1. * @return Filter decision */ - public open fun head(node: Node, depth: Int): FilterResult + public fun head(node: Node, depth: Int): FilterResult /** * Callback for when a node is last visited, after all of its descendants have been visited. diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/QueryParser.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/QueryParser.kt index 584add7a..c7785fd3 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/QueryParser.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/QueryParser.kt @@ -69,7 +69,7 @@ internal class QueryParser private constructor(query: String) { '>' -> { val run: ImmediateParentRun = if (currentEval is ImmediateParentRun) { - currentEval as ImmediateParentRun + currentEval } else { ImmediateParentRun( currentEval!!, @@ -98,7 +98,7 @@ internal class QueryParser private constructor(query: String) { ',' -> { val or: CombiningEvaluator.Or if (currentEval is CombiningEvaluator.Or) { - or = currentEval as CombiningEvaluator.Or + or = currentEval } else { or = CombiningEvaluator.Or() or.add(currentEval!!) @@ -284,11 +284,10 @@ internal class QueryParser private constructor(query: String) { * @param query CSS query */ init { - var query = query Validate.notEmpty(query) - query = query.trim { it <= ' ' } - this.query = query - tq = TokenQueue(query) + val trimmedQuery = query.trim { it <= ' ' } + this.query = trimmedQuery + tq = TokenQueue(trimmedQuery) } private fun cssNthChild(backwards: Boolean, ofType: Boolean): Evaluator { diff --git a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/StructuralEvaluator.kt b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/StructuralEvaluator.kt index 7ebf7ee4..0ff01151 100644 --- a/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/StructuralEvaluator.kt +++ b/ksoup/src/commonMain/kotlin/com/fleeksoft/ksoup/select/StructuralEvaluator.kt @@ -67,7 +67,7 @@ internal abstract class StructuralEvaluator(evaluator: Evaluator) : Evaluator() for (i in 0 until element.childNodeSize()) { val node: Node = element.childNode(i) if (node is Element) { - val match: Element? = finder.find(element, node as Element) + val match: Element? = finder.find(element, node) if (match != null) return true } } From 82c2a6e3ba6d42b004fa57a4a46044076bf8c640 Mon Sep 17 00:00:00 2001 From: sabeeh Date: Fri, 24 Nov 2023 02:54:45 +0400 Subject: [PATCH 10/10] Bump version to 0.0.5, fixing issues #2 and #3 --- README.md | 4 ++-- gradle/libs.versions.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 06a92694..9ddf95d9 100644 --- a/README.md +++ b/README.md @@ -26,11 +26,11 @@ Ksoup is adept at handling all varieties of HTML found in the wild. ### Ksoup is published on Maven Central ```Kotlin commonMain.dependencies { - implementation("com.fleeksoft.ksoup:ksoup:0.0.4") + implementation("com.fleeksoft.ksoup:ksoup:0.0.5") // Optional: Include only if you need to use network request functions such as // Ksoup.parseGetRequest, Ksoup.parseSubmitRequest, and Ksoup.parsePostRequest - implementation("com.fleeksoft.ksoup:ksoup-network:0.0.4") + implementation("com.fleeksoft.ksoup:ksoup-network:0.0.5") } ``` diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c40cd850..4fc8ec39 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ agp = "8.1.3" kotlin = "1.9.20" compileSdk = "34" minSdk = "21" -libraryVersion = "0.0.4" +libraryVersion = "0.0.5" junitJupiter = "5.9.3" compose = "1.5.4" compose-compiler = "1.5.4"