diff --git a/.autotest b/.autotest
deleted file mode 100644
index 878238aca7..0000000000
--- a/.autotest
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- ruby -*-
-
-begin
- require 'autotest/fsevent'
-rescue LoadError
-end
-
-Autotest.add_hook :initialize do |at|
- at.add_exception /bundle$/
- at.add_exception /\.git/
-end
-
-Autotest.add_hook :run_command do |at|
- at.unit_diff = 'cat'
- system "rake compile"
-end
-
-Autotest.add_hook :ran_command do |at|
- File.open('/tmp/autotest.txt', 'wb') { |f|
- f.write(at.results.join)
- }
-end
diff --git a/.cross_rubies b/.cross_rubies
index 9810448bbe..6f52404a8d 100644
--- a/.cross_rubies
+++ b/.cross_rubies
@@ -1,8 +1,32 @@
-2.6.0:i686-w64-mingw32
-2.6.0:x86_64-w64-mingw32
-2.5.0:i686-w64-mingw32
-2.5.0:x86_64-w64-mingw32
-2.4.0:i686-w64-mingw32
-2.4.0:x86_64-w64-mingw32
-2.3.0:i686-w64-mingw32
-2.3.0:x86_64-w64-mingw32
+2.7.0:aarch64-linux
+2.7.0:arm-linux
+2.7.0:arm64-darwin
+2.7.0:x64-mingw32
+2.7.0:x86-linux
+2.7.0:x86-mingw32
+2.7.0:x86_64-darwin
+2.7.0:x86_64-linux
+3.0.0:aarch64-linux
+3.0.0:arm-linux
+3.0.0:arm64-darwin
+3.0.0:x64-mingw32
+3.0.0:x86-linux
+3.0.0:x86-mingw32
+3.0.0:x86_64-darwin
+3.0.0:x86_64-linux
+3.1.0:aarch64-linux
+3.1.0:arm-linux
+3.1.0:arm64-darwin
+3.1.0:x64-mingw-ucrt
+3.1.0:x86-linux
+3.1.0:x86-mingw32
+3.1.0:x86_64-darwin
+3.1.0:x86_64-linux
+3.2.0:aarch64-linux
+3.2.0:arm-linux
+3.2.0:arm64-darwin
+3.2.0:x64-mingw-ucrt
+3.2.0:x86-linux
+3.2.0:x86-mingw32
+3.2.0:x86_64-darwin
+3.2.0:x86_64-linux
diff --git a/.editorconfig b/.editorconfig
index e5dd4f83fd..fb6e656d50 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -14,4 +14,4 @@ indent_size = 2
[**.java]
indent_style = space
-indent_size = 4
+indent_size = 2
diff --git a/.gemtest b/.gemtest
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000000..0716b3a33d
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,3 @@
+github: flavorjones
+tidelift: rubygems/nokogiri
+open_collective: nokogiri
diff --git a/.github/ISSUE_TEMPLATE/bug-report-or-help-request.md b/.github/ISSUE_TEMPLATE/1-bug-report.md
similarity index 77%
rename from .github/ISSUE_TEMPLATE/bug-report-or-help-request.md
rename to .github/ISSUE_TEMPLATE/1-bug-report.md
index b5077193ba..297cd4de42 100644
--- a/.github/ISSUE_TEMPLATE/bug-report-or-help-request.md
+++ b/.github/ISSUE_TEMPLATE/1-bug-report.md
@@ -1,24 +1,27 @@
---
-name: Bug Report or Help Request
-about: Create a report to help us improve
-title: ''
-labels: ''
-assignees: ''
+name: "Bug Report"
+about: "Open an issue to help us improve!"
+title: "[bug]"
+labels: "state/needs-triage"
+assignees: ""
---
+
+**Please describe the bug**
-**Describe the bug**
+
-A clear and concise description of what the bug is. Please include as much context as you can about what you are trying to do.
-
-
-**To Reproduce**
+**Help us reproduce what you're seeing**
+
**Expected behavior**
+
**Environment**
+
**Additional context**
+
diff --git a/.github/ISSUE_TEMPLATE/2-installation-difficulties.md b/.github/ISSUE_TEMPLATE/2-installation-difficulties.md
new file mode 100644
index 0000000000..17929f6c70
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/2-installation-difficulties.md
@@ -0,0 +1,76 @@
+---
+name: "Installation Difficulties"
+about: "If you're having trouble installing Nokogiri ..."
+title: "[install]"
+labels: "topic/installation"
+assignees: ""
+
+---
+
+**Have you read and followed the installation tutorial at http://www.nokogiri.org/tutorials/installing_nokogiri.html?**
+
+- [ ] Yes!
+
+
+**What is the complete output of `gem install` or `bundle install`?**
+
+
+
+```
+the output goes here
+```
+
+
+**If installation completed but is broken, what is the complete output from `nokogiri -v`?**
+
+
+
+```
+the output of "nokogiri -v" goes here
+```
+
+
+
+**If installation failed during compilation, what are the complete contents of the `mkmf.log` file generated during the failed installation?**
+
+
+
+```
+the mkmf.log file contents go here
+```
+
+
+**Tell us about your system!**
+
+What is the output from `ruby -v`?
+
+What is the output from `gem -v`?
+
+What is the output from `gem env`?
+
+```
+the output of "gem env" output goes here
+```
+
+
+If you're using Bundler:
+- what is the output from `bundle version`?
+- what is the output from `bundle config`? (Take care to redact any credentials)
+
+```
+the output of "bundle config" goes here
+```
+
+If you're on MacOS, please note:
+- the version of XCode you have installed (if you know)
+- the output of `gcc -v` or `clang -v`
+
+If Linux or a BSD variant, please note:
+- the distro you're using
+- the output of `uname -a`
+- the contents of `/etc/lsb-release`.
+
+If Windows, please note:
+- whether you're installing the precompiled gems, or compiling yourself with DevKit
+- the version of RubyInstaller you've installed
+- or if you're not using RubyInstaller, how did you install Ruby?
diff --git a/.github/ISSUE_TEMPLATE/3-help-request.md b/.github/ISSUE_TEMPLATE/3-help-request.md
new file mode 100644
index 0000000000..fec33dfaaf
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/3-help-request.md
@@ -0,0 +1,58 @@
+---
+name: "Help Request"
+about: "If something is confusing or you need a helping hand ..."
+title: "[help]"
+labels: "meta/user-help"
+assignees: ""
+
+---
+
+**What problem are you trying to solve?**
+
+
+
+**Please show your code!**
+
+
+
+
+**Environment**
+
+
+
+**Additional context**
+
+
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000000..138b21e00a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,4 @@
+contact_links:
+ - name: Nokogiri Discussion Board
+ url: https://github.com/sparklemotion/nokogiri/discussions
+ about: Start a thread about a new feature idea, read the RFCs, ask and answer general questions.
diff --git a/.github/ISSUE_TEMPLATE/installation-difficulties.md b/.github/ISSUE_TEMPLATE/installation-difficulties.md
deleted file mode 100644
index fee38a0689..0000000000
--- a/.github/ISSUE_TEMPLATE/installation-difficulties.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-name: Installation Difficulties
-about: If you're having trouble installing Nokogiri ...
-title: Installation difficulties
-labels: ''
-assignees: ''
-
----
-
-**Have you read and followed the advice in the installation tutorial at http://www.nokogiri.org/tutorials/installing_nokogiri.html?**
-
-**What is the complete output of `gem install`?**
-
-Please make sure the escape the file contents with triple-backticks.
-
-
-**What are the complete contents of the `mkmf.log` file generated during the failed installation?**
-
-Please make sure the escape the file contents with triple-backticks.
-
-
-**What operating system are you using?**
-
-Are you using Linux, MacOS, Windows, a BSD variant, or something else entirely?
-
-If MacOS, please note the version of XCode you have installed.
-
-If Linux, please include the output of `uname -a` and the contents of `/etc/lsb-release`.
-
-If Windows, please note whether you're installing the precompiled gems, or compiling yourself with DevKit. Also please note the version of RubyInstaller you've installed.
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 55ce82bede..d17a637918 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,24 +1,33 @@
----
-
-Thank you for contributing to Nokogiri! To help us prioritize, please take care to answer the questions below when you submit this pull request.
-
+
**What problem is this PR intended to solve?**
-If there is an existing issue that describes this, feel free to simply link to that issue.
-
-Otherwise, please provide enough context for the Nokogiri maintainers to understand your intent.
-
+
**Have you included adequate test coverage?**
-We have a thorough test suite that allows us to create releases confidently and prevent accidental regressions. Any proposed change in behavior __must__ be accompanied by tests.
-
-If possible, please try to write the tests so that they communicate intent.
-
-
-**Does this change affect the C or the Java implementations?**
-
-If you're proposing a change to the C implementation, has the behavior change been made to the Java code as well? And vice versa?
-
-If not, that may be OK, just please note it here.
+
+
+**Does this change affect the behavior of either the C or the Java implementations?**
+
+
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000000..8076dd7a64
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,11 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "bundler" # See documentation for possible values
+ directory: "/" # Location of package manifests
+ schedule:
+ interval: "weekly"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000000..ccb967f4c9
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,728 @@
+name: ci
+concurrency:
+ group: "${{github.workflow}}-${{github.ref}}"
+ cancel-in-progress: true
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: "0 8 * * 3" # At 08:00 on Wednesday # https://crontab.guru/#0_8_*_*_3
+ push:
+ branches:
+ - main
+ - v*.*.x
+ tags:
+ - v*.*.*
+ pull_request:
+ types: [opened, synchronize]
+ branches:
+ - '*'
+
+jobs:
+ #
+ # SECTION pre-checks for fast feedback loops, and to gate the rest of the suite
+ #
+ rubocop:
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:mri-3.1
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - run: bundle install --local || bundle install
+ - run: bundle exec rake rubocop
+
+ basic:
+ needs: ["rubocop"]
+ strategy:
+ fail-fast: false
+ matrix:
+ image: ["ubuntu", "ubuntu32"]
+ sys: ["enable"]
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:${{matrix.image}}
+ env:
+ NOKOGIRI_TEST_GC_LEVEL: normal # for fast feedback
+ steps:
+ - uses: actions/checkout@v1 # v1 because of https://github.com/actions/checkout/issues/334
+ with:
+ submodules: true
+ - run: bundle install --local || bundle install
+ - run: bundle exec rake compile -- --${{matrix.sys}}-system-libraries
+ - run: bundle exec rake test
+ - run: bundle exec rake test:bench
+
+ gumbo:
+ needs: ["rubocop"]
+ strategy:
+ fail-fast: false
+ matrix:
+ plat: ["ubuntu", "windows", "macos"]
+ runs-on: ${{matrix.plat}}-latest
+ steps:
+ - name: configure git crlf
+ if: matrix.plat == 'windows'
+ run: |
+ git config --system core.autocrlf false
+ git config --system core.eol lf
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: "3.1"
+ bundler-cache: true
+ bundler: latest
+ - run: bundle exec rake gumbo:test
+
+ #
+ # SECTION run the test suite across a broad matrix of rubies, configs, and systems
+ #
+ linux:
+ needs: ["basic"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["enable", "disable"]
+ ruby: ["2.7", "3.0", "3.1", "3.2"]
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:mri-${{matrix.ruby}}
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/cache@v3
+ if: matrix.sys == 'disable'
+ with:
+ path: ports
+ key: ports-ubuntu-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}}
+ - run: bundle install --local || bundle install
+ - run: bundle exec rake compile -- --${{matrix.sys}}-system-libraries
+ - run: bundle exec rake test
+ - run: bundle exec rake test:bench
+
+ valgrind:
+ needs: ["linux"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["enable", "disable"]
+ ruby: ["2.7", "3.0", "3.1", "3.2"]
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:mri-${{matrix.ruby}}
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/cache@v3
+ if: matrix.sys == 'disable'
+ with:
+ path: ports
+ key: ports-ubuntu-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}}
+ - run: bundle install --local || bundle install
+ - run: bundle exec rake compile -- --${{matrix.sys}}-system-libraries
+ - run: bundle exec rake test:valgrind
+
+ musl:
+ needs: ["basic"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["enable"]
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:alpine
+ steps:
+ - uses: actions/checkout@v1 # v1 because of https://github.com/actions/checkout/issues/334
+ with:
+ submodules: true
+ # skip cache because of https://github.com/actions/cache/issues/675
+ - run: bundle install --local || bundle install
+ - run: bundle exec rake compile -- --${{matrix.sys}}-system-libraries
+ - run: bundle exec rake test
+
+ musl-valgrind:
+ needs: ["musl"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["disable"]
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:alpine
+ steps:
+ - uses: actions/checkout@v1 # v1 because of https://github.com/actions/checkout/issues/334
+ with:
+ submodules: true
+ # skip cache because of https://github.com/actions/cache/issues/675
+ - run: bundle install --local || bundle install
+ - run: bundle exec rake compile -- --${{matrix.sys}}-system-libraries
+ - run: bundle exec rake test:valgrind
+
+ libxmlruby:
+ needs: ["basic"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["enable"]
+ ruby: ["3.1"]
+ env:
+ BUNDLE_GEMFILE: "Gemfile-libxml-ruby"
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:mri-${{matrix.ruby}}
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/cache@v3
+ if: matrix.sys == 'disable'
+ with:
+ path: ports
+ key: ports-ubuntu-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}}
+ - run: bundle install --local || bundle install
+ - run: bundle exec rake compile -- --${{matrix.sys}}-system-libraries
+ - run: bundle exec rake test
+
+ libxmlruby-valgrind:
+ needs: ["libxmlruby"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["disable"]
+ ruby: ["3.1"]
+ env:
+ BUNDLE_GEMFILE: "Gemfile-libxml-ruby"
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:mri-${{matrix.ruby}}
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/cache@v3
+ if: matrix.sys == 'disable'
+ with:
+ path: ports
+ key: ports-ubuntu-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}}
+ - run: bundle install --local || bundle install
+ - run: bundle exec rake compile -- --${{matrix.sys}}-system-libraries
+ - run: bundle exec rake test:valgrind
+
+ osx:
+ needs: ["basic"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["enable", "disable"]
+ ruby: ["2.7", "3.0", "3.1", "3.2"]
+ runs-on: macos-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: ${{matrix.ruby}}
+ bundler-cache: true
+ bundler: latest
+ - uses: actions/cache@v3
+ if: matrix.sys == 'disable'
+ with:
+ path: ports
+ key: ports-macos-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}}
+ - run: bundle exec rake compile -- --${{matrix.sys}}-system-libraries
+ - run: bundle exec rake test
+
+ windows:
+ needs: ["basic"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["enable", "disable"]
+ ruby: ["2.7", "3.0", "3.1", "3.2", "mingw"]
+ runs-on: windows-2022
+ steps:
+ - name: configure git crlf
+ run: |
+ git config --system core.autocrlf false
+ git config --system core.eol lf
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby-pkgs@v1
+ with:
+ ruby-version: "${{matrix.ruby}}"
+ mingw: "libxml2 libxslt"
+ bundler-cache: true
+ bundler: latest
+ - uses: actions/cache@v3
+ if: matrix.sys == 'disable'
+ with:
+ path: ports
+ key: ports-windows-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}}
+ - run: bundle exec rake compile -- --${{matrix.sys}}-system-libraries
+ - run: bundle exec rake test
+
+ jruby:
+ needs: ["basic"]
+ strategy:
+ fail-fast: false
+ matrix:
+ ruby: ["jruby-9.4"]
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: ${{matrix.ruby}}
+ bundler-cache: true
+ bundler: latest
+ - run: bundle exec rake compile
+ - run: bundle exec rake test
+ - run: bundle exec rake test:bench
+
+ truffleruby-head:
+ needs: ["basic"]
+ strategy:
+ fail-fast: false
+ matrix:
+ flags:
+ - "--disable-system-libraries --disable-static"
+ - "--disable-system-libraries --enable-static"
+ - "--enable-system-libraries"
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:truffle-nightly
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/cache@v3
+ with:
+ path: ports/archives
+ key: tarballs-ubuntu-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}}
+ - run: bundle install --local || bundle install
+ - run: bundle exec rake compile -- ${{matrix.flags}}
+ - run: bundle exec rake test
+
+ bsd:
+ continue-on-error: true # we're seeing VMs hang and fail the whole workflow
+ needs: ["basic"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["enable", "disable"]
+ runs-on: macos-12
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: vmactions/freebsd-vm@v0
+ with:
+ usesh: true
+ prepare: pkg install -y ruby devel/ruby-gems pkgconf libxml2 libxslt
+ run: |
+ gem install bundler
+ bundle install --local || bundle install
+ bundle exec rake compile -- --${{matrix.sys}}-system-libraries
+ bundle exec rake test
+
+ #
+ # SECTION let's look for memory leaks
+ #
+ memcheck:
+ needs: ["basic"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["disable"]
+ ruby: ["3.1"]
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:mri-${{matrix.ruby}}
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/cache@v3
+ if: matrix.sys == 'disable'
+ with:
+ path: ports
+ key: ports-ubuntu-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}}
+ - run: bundle install --local || bundle install
+ - run: bundle exec rake compile -- --${{matrix.sys}}-system-libraries
+ - run: bundle exec rake test:memcheck
+
+ #
+ # SECTION the end-to-end gem installation tests
+ #
+ rcd_image_version:
+ needs: ["basic"]
+ runs-on: ubuntu-latest
+ outputs:
+ rcd_image_version: ${{steps.rcd_image_version.outputs.rcd_image_version}}
+ steps:
+ - uses: actions/checkout@v3
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: "3.1"
+ bundler-cache: true
+ bundler: latest
+ - id: rcd_image_version
+ run: bundle exec ruby -e 'require "rake_compiler_dock"; puts "rcd_image_version=#{RakeCompilerDock::IMAGE_VERSION}"' >> $GITHUB_OUTPUT
+
+ generic-package:
+ needs: ["rcd_image_version"]
+ name: "generic-package"
+ runs-on: ubuntu-latest
+ container:
+ image: "ghcr.io/rake-compiler/rake-compiler-dock-image:${{needs.rcd_image_version.outputs.rcd_image_version}}-mri-x86_64-linux"
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - run: git config --global --add safe.directory /__w/nokogiri/nokogiri # shrug
+ - uses: actions/cache@v3
+ with:
+ path: ports/archives
+ key: tarballs-ubuntu-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}}
+ - run: ./scripts/test-gem-build gems ruby
+ - uses: actions/upload-artifact@v3
+ with:
+ name: generic-gem
+ path: gems
+ retention-days: 1
+
+ generic-linux-install:
+ needs: ["generic-package"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["enable", "disable"]
+ ruby: ["2.7", "3.0", "3.1", "3.2"]
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby-pkgs@v1
+ with:
+ ruby-version: "${{matrix.ruby}}"
+ apt-get: "libxml2-dev libxslt1-dev pkg-config"
+ - uses: actions/download-artifact@v3
+ with:
+ name: generic-gem
+ path: gems
+ - run: ./scripts/test-gem-install gems --${{matrix.sys}}-system-libraries
+
+ generic-darwin-install:
+ needs: ["generic-package"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["enable", "disable"]
+ ruby: ["2.7", "3.0", "3.1", "3.2"]
+ runs-on: macos-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: "${{matrix.ruby}}"
+ - uses: actions/download-artifact@v3
+ with:
+ name: generic-gem
+ path: gems
+ - run: ./scripts/test-gem-install gems --${{matrix.sys}}-system-libraries
+
+ generic-windows-install:
+ needs: ["generic-package"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["enable", "disable"]
+ ruby: ["2.7", "3.0"]
+ runs-on: windows-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby-pkgs@v1
+ with:
+ ruby-version: "${{matrix.ruby}}"
+ mingw: "libxml2 libxslt"
+ - uses: actions/download-artifact@v3
+ with:
+ name: generic-gem
+ path: gems
+ - run: ./scripts/test-gem-install gems --${{matrix.sys}}-system-libraries
+ shell: bash
+
+ generic-windows-install-ucrt:
+ needs: ["generic-package"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["enable", "disable"]
+ ruby: ["3.1", "3.2"]
+ runs-on: windows-2022
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby-pkgs@v1
+ with:
+ ruby-version: "${{matrix.ruby}}"
+ mingw: "libxml2 libxslt"
+ - uses: actions/download-artifact@v3
+ with:
+ name: generic-gem
+ path: gems
+ - run: ./scripts/test-gem-install gems --${{matrix.sys}}-system-libraries
+ shell: bash
+
+ cruby-package:
+ needs: ["rcd_image_version"]
+ name: "cruby-package"
+ strategy:
+ fail-fast: false
+ matrix:
+ plat:
+ - "aarch64-linux"
+ - "arm-linux"
+ - "arm64-darwin" # github actions does not support this runtime as of 2022-12, but let's build anyway
+ - "x64-mingw-ucrt"
+ - "x64-mingw32"
+ - "x86-linux"
+ - "x86-mingw32" # github actions does not support this runtime as of 2022-12, but let's build anyway
+ - "x86_64-darwin"
+ - "x86_64-linux"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/cache@v3
+ with:
+ path: ports/archives
+ key: tarballs-ubuntu-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}}
+ - env:
+ DOCKER_IMAGE: "ghcr.io/rake-compiler/rake-compiler-dock-image:${{needs.rcd_image_version.outputs.rcd_image_version}}-mri-${{matrix.plat}}"
+ run: |
+ docker run --rm -v "$(pwd):/nokogiri" -w /nokogiri \
+ ${DOCKER_IMAGE} \
+ ./scripts/test-gem-build gems ${{matrix.plat}}
+ - uses: actions/upload-artifact@v3
+ with:
+ name: "cruby-${{matrix.plat}}-gem"
+ path: gems
+ retention-days: 1
+
+ cruby-x86-linux-install:
+ needs: ["cruby-package"]
+ strategy:
+ fail-fast: false
+ matrix:
+ ruby: ["2.7", "3.0", "3.1", "3.2"]
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/download-artifact@v3
+ with:
+ name: cruby-x86-linux-gem
+ path: gems
+ - run: |
+ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
+ docker run --rm -v "$(pwd):/nokogiri" -w /nokogiri \
+ --platform=linux/386 \
+ ruby:${{matrix.ruby}} \
+ ./scripts/test-gem-install gems
+
+ cruby-aarch64-linux-install:
+ needs: ["cruby-package"]
+ strategy:
+ fail-fast: false
+ matrix:
+ ruby: ["2.7", "3.0", "3.1", "3.2"]
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/download-artifact@v3
+ with:
+ name: cruby-aarch64-linux-gem
+ path: gems
+ - run: |
+ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
+ docker run --rm -v "$(pwd):/nokogiri" -w /nokogiri \
+ --platform=linux/arm64/v8 \
+ ruby:${{matrix.ruby}} \
+ ./scripts/test-gem-install gems
+
+ cruby-arm-linux-install:
+ needs: ["cruby-package"]
+ strategy:
+ fail-fast: false
+ matrix:
+ ruby: ["2.7", "3.0", "3.1", "3.2"]
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/download-artifact@v3
+ with:
+ name: cruby-arm-linux-gem
+ path: gems
+ - run: |
+ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
+ docker run --rm -v "$(pwd):/nokogiri" -w /nokogiri \
+ --platform=linux/arm/v7 \
+ ruby:${{matrix.ruby}} \
+ ./scripts/test-gem-install gems
+
+ cruby-x86_64-linux-install:
+ needs: ["cruby-package"]
+ strategy:
+ fail-fast: false
+ matrix:
+ ruby: ["2.7", "3.0", "3.1", "3.2"]
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: "${{matrix.ruby}}"
+ - uses: actions/download-artifact@v3
+ with:
+ name: cruby-x86_64-linux-gem
+ path: gems
+ - run: ./scripts/test-gem-install gems
+
+ cruby-x86_64-musl-install:
+ needs: ["cruby-package"]
+ strategy:
+ fail-fast: false
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:alpine
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/download-artifact@v3
+ with:
+ name: cruby-x86_64-linux-gem
+ path: gems
+ - run: ./scripts/test-gem-install gems
+
+ cruby-x86_64-darwin-install:
+ needs: ["cruby-package"]
+ strategy:
+ fail-fast: false
+ matrix:
+ ruby: ["2.7", "3.0", "3.1", "3.2"]
+ runs-on: macos-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: "${{matrix.ruby}}"
+ - uses: actions/download-artifact@v3
+ with:
+ name: cruby-x86_64-darwin-gem
+ path: gems
+ - run: ./scripts/test-gem-install gems
+
+ cruby-x64-mingw32-install:
+ needs: ["cruby-package"]
+ strategy:
+ fail-fast: false
+ matrix:
+ ruby: ["2.7", "3.0"]
+ runs-on: windows-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: "${{matrix.ruby}}"
+ - uses: actions/download-artifact@v3
+ with:
+ name: cruby-x64-mingw32-gem
+ path: gems
+ - run: ./scripts/test-gem-install gems
+ shell: bash
+
+ cruby-x64-mingw-ucrt-install:
+ needs: ["cruby-package"]
+ strategy:
+ fail-fast: false
+ matrix:
+ ruby: ["3.1", "3.2"]
+ runs-on: windows-2022
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: "${{matrix.ruby}}"
+ - uses: actions/download-artifact@v3
+ with:
+ name: cruby-x64-mingw-ucrt-gem
+ path: gems
+ - run: ./scripts/test-gem-install gems
+ shell: bash
+
+ jruby-package:
+ needs: ["rcd_image_version"]
+ name: "jruby-package"
+ runs-on: ubuntu-latest
+ container:
+ image: "ghcr.io/rake-compiler/rake-compiler-dock-image:${{needs.rcd_image_version.outputs.rcd_image_version}}-jruby"
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - run: ./scripts/test-gem-build gems java
+ - uses: actions/upload-artifact@v3
+ with:
+ name: jruby-gem
+ path: gems
+ retention-days: 1
+
+ jruby-install:
+ needs: ["jruby-package"]
+ strategy:
+ fail-fast: false
+ matrix:
+ ruby: ["jruby-9.4"]
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: "${{matrix.ruby}}"
+ - uses: actions/download-artifact@v3
+ with:
+ name: jruby-gem
+ path: gems
+ - run: ./scripts/test-gem-install gems
diff --git a/.github/workflows/downstream.yml b/.github/workflows/downstream.yml
new file mode 100644
index 0000000000..bc1f8705c7
--- /dev/null
+++ b/.github/workflows/downstream.yml
@@ -0,0 +1,78 @@
+name: downstream
+concurrency:
+ group: "${{github.workflow}}-${{github.ref}}"
+ cancel-in-progress: true
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: "0 8 * * 1,3,5" # At 08:00 on Monday, Wednesday, and Friday # https://crontab.guru/#0_8_*_*_1,3,5
+ push:
+ branches:
+ - main
+ - v*.*.x
+ tags:
+ - v*.*.*
+ pull_request:
+ types: [opened, synchronize]
+ branches:
+ - '*'
+
+jobs:
+ downstream:
+ name: downstream-${{matrix.name}}
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - url: https://github.com/flavorjones/loofah
+ name: loofah
+ command: "bundle exec rake test"
+ - url: https://github.com/rails/rails-html-sanitizer
+ name: rails-html-sanitizer
+ command: "bundle exec rake test"
+ - url: https://github.com/rgrove/sanitize
+ name: sanitize
+ command: "bundle exec rake test"
+ - url: https://github.com/ebeigarts/signer
+ name: signer
+ command: "bundle exec rake spec"
+ - url: https://github.com/WinRb/Viewpoint
+ name: viewpoint
+ command: "bundle exec rspec spec"
+ - url: https://github.com/rails/rails
+ name: xmlmini
+ command: "cd activesupport && bundle exec rake test TESTOPTS=-n/XmlMini/"
+ - url: https://github.com/pythonicrubyist/creek
+ name: creek
+ command: "bundle exec rake spec"
+ # - url: https://github.com/instructure/nokogiri-xmlsec-instructure
+ # name: nokogiri-xmlsec-instructure
+ # precommand: "apt install -y libxmlsec1-dev"
+ # command: "bundle exec rake compile rspec"
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:mri-3.1
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/cache@v3
+ with:
+ path: ports
+ key: ports-ubuntu-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}}
+ - if: matrix.precommand
+ run: ${{matrix.precommand}}
+ - run: gem install bundler -v ">= 2.3.22" # for "add --path"
+ - run: bundle install --local || bundle install
+ - run: bundle exec rake compile
+ - run: git clone --depth=1 ${{matrix.url}} ${{matrix.name}}
+ - name: ${{matrix.name}} test suite
+ working-directory: ${{matrix.name}}
+ run: |
+ bundle remove nokogiri || true
+ bundle add nokogiri --path=".."
+ if grep "add_development_dependency.*\bbundler\b" *gemspec ; then
+ sed -i 's/.*add_development_dependency.*\bbundler\b.*//' *gemspec
+ fi
+ bundle install --local || bundle install
+ ${{matrix.command}}
diff --git a/.github/workflows/generate-ci-images.yml b/.github/workflows/generate-ci-images.yml
new file mode 100644
index 0000000000..58cf93aa1f
--- /dev/null
+++ b/.github/workflows/generate-ci-images.yml
@@ -0,0 +1,37 @@
+# DO NOT EDIT
+# this file is automatically generated by the "docker:pipeline" rake task
+name: Generate CI Images
+on:
+ workflow_dispatch: {}
+ schedule:
+ - cron: "0 5 * * 3" # At 05:00 on Wednesday # https://crontab.guru/#0_5_*_*_3
+# reference: https://github.com/marketplace/actions/build-and-push-docker-images
+jobs:
+ build_images:
+ strategy:
+ fail-fast: false
+ matrix:
+ tag: ["alpine", "mri-2.7", "mri-3.0", "mri-3.1", "mri-3.2", "truffle-nightly", "ubuntu", "ubuntu32"]
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: "3.1"
+ bundler-cache: true
+ bundler: latest
+ - uses: docker/setup-buildx-action@v2
+ - uses: docker/login-action@v2
+ with:
+ registry: ghcr.io
+ username: ${{github.actor}}
+ password: ${{secrets.GITHUB_TOKEN}}
+ - name: ${{matrix.tag}}
+ uses: docker/build-push-action@v3
+ with:
+ context: "."
+ push: true
+ tags: ghcr.io/sparklemotion/nokogiri-test:${{matrix.tag}}
+ file: oci-images/nokogiri-test/${{matrix.tag}}.dockerfile
diff --git a/.github/workflows/upstream.yml b/.github/workflows/upstream.yml
new file mode 100644
index 0000000000..1c63c8078a
--- /dev/null
+++ b/.github/workflows/upstream.yml
@@ -0,0 +1,156 @@
+name: upstream
+concurrency:
+ group: "${{github.workflow}}-${{github.ref}}"
+ cancel-in-progress: true
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: "0 8 * * 1,3,5" # At 08:00 on Monday, Wednesday, and Friday # https://crontab.guru/#0_8_*_*_1,3,5
+ pull_request:
+ types: [opened, synchronize]
+ branches:
+ - '*'
+ paths:
+ - .github/workflows/upstream.yml # this file
+
+jobs:
+ xmlsoft-head:
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:mri-3.1
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - name: Setup libxml2
+ run: |
+ git clone --depth=1 https://gitlab.gnome.org/GNOME/libxml2
+ cd libxml2
+ env NOCONFIGURE=t ./autogen.sh
+ - name: Setup libxslt
+ run: |
+ git clone --depth=1 https://gitlab.gnome.org/GNOME/libxslt
+ cd libxslt
+ env NOCONFIGURE=t ./autogen.sh
+ - name: "Run bundle install"
+ run: "bundle install --local || bundle install"
+ - name: "Compile against libxml2 and libxslt source directories"
+ run: "bundle exec rake compile -- --with-xml2-source-dir=${GITHUB_WORKSPACE}/libxml2 --with-xslt-source-dir=${GITHUB_WORKSPACE}/libxslt"
+ - run: "bundle exec rake test"
+
+ xmlsoft-head-valgrind:
+ needs: ["xmlsoft-head"]
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:mri-3.1
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - name: Setup libxml2
+ run: |
+ git clone --depth=1 https://gitlab.gnome.org/GNOME/libxml2
+ cd libxml2
+ env NOCONFIGURE=t ./autogen.sh
+ - name: Setup libxslt
+ run: |
+ git clone --depth=1 https://gitlab.gnome.org/GNOME/libxslt
+ cd libxslt
+ env NOCONFIGURE=t ./autogen.sh
+ - name: "Run bundle install"
+ run: "bundle install --local || bundle install"
+ - name: "Compile against libxml2 and libxslt source directories"
+ run: "bundle exec rake compile -- --with-xml2-source-dir=${GITHUB_WORKSPACE}/libxml2 --with-xslt-source-dir=${GITHUB_WORKSPACE}/libxslt"
+ - run: "bundle exec rake test:valgrind"
+
+ ruby-head:
+ strategy:
+ fail-fast: false
+ matrix:
+ plat: ["ubuntu", "windows", "macos"]
+ sys: ["enable", "disable"]
+ runs-on: ${{matrix.plat}}-latest
+ steps:
+ - name: configure git crlf
+ if: matrix.plat == 'windows'
+ run: |
+ git config --system core.autocrlf false
+ git config --system core.eol lf
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby-pkgs@v1
+ with:
+ ruby-version: "head"
+ apt-get: "libxml2-dev libxslt1-dev pkg-config"
+ mingw: "_upgrade_ libxml2 libxslt pkgconf"
+ bundler-cache: true
+ bundler: latest
+ - uses: actions/cache@v3
+ if: matrix.sys == 'disable'
+ with:
+ path: ports
+ key: ports-${{matrix.plat}}-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}}
+ - run: bundle exec rake compile -- --${{matrix.sys}}-system-libraries
+ - run: bundle exec rake test
+
+ ruby-head-valgrind:
+ needs: ["ruby-head"]
+ strategy:
+ fail-fast: false
+ matrix:
+ sys: ["enable", "disable"]
+ runs-on: ubuntu-20.04 # warning that 22.04 binary has dwarf5 debug info that valgrind can't read
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby-pkgs@v1
+ with:
+ ruby-version: "head"
+ apt-get: "libxml2-dev libxslt1-dev pkg-config valgrind"
+ bundler-cache: true
+ bundler: latest
+ - uses: actions/cache@v3
+ if: matrix.sys == 'disable'
+ with:
+ path: ports
+ key: ports-ubuntu-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}}
+ - run: bundle exec rake compile -- --${{matrix.sys}}-system-libraries
+ - run: bundle exec rake test:valgrind
+
+ jruby-head:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: "jruby-head"
+ bundler-cache: true
+ bundler: latest
+ - run: bundle exec rake compile
+ - run: bundle exec rake test
+
+ html5lib-tests:
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/sparklemotion/nokogiri-test:mri-3.1
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/cache@v3
+ with:
+ path: ports
+ key: ports-ubuntu-${{hashFiles('dependencies.yml', 'patches/**/*.patch')}}
+ - name: Update html5lib-tests
+ run: |
+ cd test/html5lib-tests
+ git remote update origin
+ git checkout origin/master
+ git log --pretty=oneline -n1
+ - run: bundle install --local || bundle install
+ - run: bundle exec rake compile -- --disable-system-libraries
+ - run: bundle exec rake test
diff --git a/.gitignore b/.gitignore
index 8746a53f36..ade1b6109b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,37 +1,42 @@
-*.gemspec
-*.tmproj
-*~
-.*.swp
-.bundle
+# bundler
+/.bundle/
+/Gemfile*lock
+/vendor/
+
+# building and packaging
+/ext/nokogiri/**/nokogiri.dll
+/ext/nokogiri/include
+/gems/
+/lib/nokogiri/**/nokogiri.bundle
+/lib/nokogiri/**/nokogiri.so
+/lib/nokogiri/nokogiri.jar
+/pkg/
+/ports/
+/tmp/
+
+# code coverage
+/coverage/
+
+# documentation
+/html/
+
+# editors and tags
.classpath
.project
-.rake_tasks
-.ruby-gemset
-.ruby-version
-.rvmrc
.settings
-.yardoc
-Gemfile*lock
-TAGS
build
-concourse/private.yml
-concourse/images/*.generated
-coverage
-ext/java/Canna
-ext/java/nokogiri/**/*.class
-ext/nokogiri/*.dll
-gems
-lib/nokogiri/**/nokogiri.so
-lib/nokogiri/nokogiri.bundle
-lib/nokogiri/nokogiri.jar
-lib/nokogiri/nokogiri.rb
-pkg
-ports
-stash
+TAGS
tags
-test/*/*_mini.rb
-test/*_mini.rb
-test/test_jruby_footer.rb
-test/test_jruby_header.rb
-tmp
-vendor
+
+# auto-formatting
+/ext/**/*.orig
+
+# mac
+.DS_Store/
+
+# Vagrant
+/.vagrant/
+
+# directories or files named after issues, and debugging
+/[0-9][0-9][0-9]*
+/*.log
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000000..57c9b57f2f
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,4 @@
+[submodule "test/html5lib-tests"]
+ path = test/html5lib-tests
+ url = https://github.com/html5lib/html5lib-tests.git
+ branch = master
diff --git a/.hoerc b/.hoerc
deleted file mode 100644
index 49e6572a18..0000000000
--- a/.hoerc
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- yaml -*-
----
-# this regex is what `rake check_manifest` should consider excluded from the gem
-exclude: !ruby/regexp '/
-(^\.\/
- ((\.git
- |.yardoc
- |concourse
- |gems
- |ports
- |suppressions
- |tasks
- |test
- |tmp
- )\/)
- |\.(autotest
- |cross_rubies
- |editorconfig
- |gemtest
- |github
- |gitignore
- |hoerc
- |travis\.yml
- )
- |Gemfile.*
- |Manifest.txt
- |Rakefile
- |appveyor\.yml
- |build_all
- |CHANGELOG.md
- |CODE_OF_CONDUCT.md
- |CONTRIBUTING.md
- |ROADMAP.md
- |SECURITY.md
- |STANDARD_RESPONSES.md
- |Y_U_NO_GEMSPEC.md
- |C_CODING_STYLE.*
- |patches/sort-patches-by-date
-)
-|\.gitkeep
-/x'
diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644
index 0000000000..8c5b9bbe6d
--- /dev/null
+++ b/.rubocop.yml
@@ -0,0 +1,23 @@
+require:
+ - rubocop-minitest
+ - rubocop-performance
+ - rubocop-rake
+inherit_gem:
+ rubocop-shopify: rubocop.yml
+inherit_from: .rubocop_todo.yml
+
+AllCops:
+ NewCops: enable
+ Exclude:
+ - 'lib/nokogiri/css/parser.rb' # generated by racc
+ - 'lib/nokogiri/css/tokenizer.rb' # generated by rex
+ - 'lib/nokogiri/jruby/nokogiri_jars.rb' # generated by jar-dependencies
+ - 'test/_test_pattern_matching.rb' # until TargetRubyVersion >= 3.0
+ TargetRubyVersion: "2.7"
+Naming/MethodName:
+ Enabled: false
+Naming/FileName:
+ Exclude:
+ - rakelib/**
+Minitest/EmptyLineBeforeAssertionMethods:
+ Enabled: false
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
new file mode 100644
index 0000000000..4f657f9b9b
--- /dev/null
+++ b/.rubocop_todo.yml
@@ -0,0 +1,69 @@
+# This configuration was generated by
+# `rubocop --auto-gen-config --exclude-limit 50`
+# on 2022-08-23 18:18:31 UTC using RuboCop version 1.35.1.
+# The point is for the user to remove these configuration records
+# one by one as the offenses are removed from the code base.
+# Note that changes in the inspected code, or installation of new
+# versions of RuboCop, may require this file to be generated again.
+
+# Offense count: 3
+Lint/MissingSuper:
+ Exclude:
+ - 'lib/nokogiri/html4/document_fragment.rb'
+ - 'lib/nokogiri/html5/document_fragment.rb'
+ - 'lib/nokogiri/xml/document_fragment.rb'
+
+# Offense count: 4
+# Configuration parameters: CountBlocks.
+Metrics/BlockNesting:
+ Max: 4
+
+# Offense count: 2
+# Configuration parameters: Max, CountKeywordArgs.
+Metrics/ParameterLists:
+ MaxOptionalParameters: 4
+
+# Offense count: 3
+# Configuration parameters: MinSize.
+Performance/CollectionLiteralInLoop:
+ Exclude:
+ - 'test/html5/test_tree_construction.rb'
+ - 'test/xml/test_dtd_encoding.rb'
+ - 'test/xml/test_node_reparenting.rb'
+
+# Offense count: 23
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: def_self, self_class
+Style/ClassMethodsDefinitions:
+ Exclude:
+ - 'lib/nokogiri/css/xpath_visitor.rb'
+ - 'lib/nokogiri/html4/document_fragment.rb'
+ - 'lib/nokogiri/html4/encoding_reader.rb'
+ - 'lib/nokogiri/html4/sax/parser_context.rb'
+ - 'lib/nokogiri/html5.rb'
+ - 'lib/nokogiri/html5/document_fragment.rb'
+ - 'lib/nokogiri/version/info.rb'
+ - 'lib/nokogiri/xml/builder.rb'
+ - 'lib/nokogiri/xml/document_fragment.rb'
+ - 'lib/nokogiri/xml/entity_decl.rb'
+ - 'lib/nokogiri/xml/sax/parser_context.rb'
+ - 'lib/nokogiri/xml/schema.rb'
+ - 'test/helper.rb'
+ - 'test/html5/test_serialize.rb'
+ - 'test/html5/test_tree_construction.rb'
+ - 'test/test_memory_leak.rb'
+ - 'test/test_soap4r_sax.rb'
+ - 'test/xml/test_entity_reference.rb'
+
+# Offense count: 2
+Style/MissingRespondToMissing:
+ Exclude:
+ - 'lib/nokogiri/xml/builder.rb'
+
+# Offense count: 73
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, IgnoredPatterns.
+# URISchemes: http, https
+Layout/LineLength:
+ Max: 250
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c613e9554e..2981f55e3d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,797 @@
# Nokogiri Changelog
+Nokogiri follows [Semantic Versioning](https://semver.org/), please see the [README.md](README.md) for details.
+
+---
+
+## 1.14.2 / 2023-02-13
+
+### Fixed
+
+* Calling `NodeSet#to_html` on an empty node set no longer raises an encoding-related exception. This bug was introduced in v1.14.0 while fixing [#2649](https://github.com/sparklemotion/nokogiri/issues/2649). [[#2784](https://github.com/sparklemotion/nokogiri/issues/2784)]
+
+
+## 1.14.1 / 2023-01-30
+
+### Fixed
+
+* Serializing documents now works again with pseudo-IO objects that don't support IO's encoding API (like rubyzip's `Zip::OutputStream`). This was a regression in v1.14.0 due to the fix for [#752](https://github.com/sparklemotion/nokogiri/issues/752) in [#2434](https://github.com/sparklemotion/nokogiri/issues/2434), and was not completely fixed by [#2753](https://github.com/sparklemotion/nokogiri/issues/2753). [[#2773](https://github.com/sparklemotion/nokogiri/issues/2773)]
+* [CRuby] Address compiler warnings about `void*` casting and old-style C function definitions.
+
+
+## 1.14.0 / 2023-01-12
+
+### Notable Changes
+
+#### Ruby
+
+This release introduces native gem support for Ruby 3.2. (Also see "Technical note" under "Changed" below.)
+
+This release ends support for:
+
+* Ruby 2.6, for which [upstream support ended 2022-04-12](https://www.ruby-lang.org/en/downloads/branches/).
+* JRuby 9.3, which is not fully compatible with Ruby 2.7+
+
+
+#### Faster, more reliable installation: Native Gem for `aarch64-linux` (aka `linux/arm64/v8`)
+
+This version of Nokogiri ships _official_ native gem support for the `aarch64-linux` platform, which should support AWS Graviton and other ARM64 Linux platforms. Please note that glibc >= 2.29 is required for aarch64-linux systems, see [Supported Platforms](https://nokogiri.org/#supported-platforms) for more information.
+
+
+#### Faster, more reliable installation: Native Gem for `arm-linux` (aka `linux/arm/v7`)
+
+This version of Nokogiri ships _experimental_ native gem support for the `arm-linux` platform. Please note that glibc >= 2.29 is required for arm-linux systems, see [Supported Platforms](https://nokogiri.org/#supported-platforms) for more information.
+
+
+#### Pattern matching
+
+This version introduces an _experimental_ pattern matching API for `XML::Attr`, `XML::Document`, `XML::DocumentFragment`, `XML::Namespace`, `XML::Node`, and `XML::NodeSet` (and their subclasses).
+
+Some documentation on what can be matched:
+
+* [`XML::Attr#deconstruct_keys`](https://nokogiri.org/rdoc/Nokogiri/XML/Attr.html?h=deconstruct#method-i-deconstruct_keys)
+* [`XML::Document#deconstruct_keys`](https://nokogiri.org/rdoc/Nokogiri/XML/Document.html?h=deconstruct#method-i-deconstruct_keys)
+* [`XML::Namespace#deconstruct_keys`](https://nokogiri.org/rdoc/Nokogiri/XML/Namespace.html?h=deconstruct+namespace#method-i-deconstruct_keys)
+* [`XML::Node#deconstruct_keys`](https://nokogiri.org/rdoc/Nokogiri/XML/Node.html?h=deconstruct#method-i-deconstruct_keys)
+* [`XML::DocumentFragment#deconstruct`](https://nokogiri.org/rdoc/Nokogiri/XML/DocumentFragment.html?h=deconstruct#method-i-deconstruct)
+* [`XML::NodeSet#deconstruct`](https://nokogiri.org/rdoc/Nokogiri/XML/NodeSet.html?h=deconstruct#method-i-deconstruct)
+
+We welcome feedback on this API at [#2360](https://github.com/sparklemotion/nokogiri/issues/2360).
+
+
+### Dependencies
+
+#### CRuby
+
+* Vendored libiconv is updated to [v1.17](https://savannah.gnu.org/forum/forum.php?forum_id=10175)
+
+#### JRuby
+
+* This version of Nokogiri uses [`jar-dependencies`](https://github.com/mkristian/jar-dependencies) to manage most of the vendored Java dependencies. `nokogiri -v` now outputs maven metadata for all Java dependencies, and `Nokogiri::VERSION_INFO` also contains this metadata. [[#2432](https://github.com/sparklemotion/nokogiri/issues/2432)]
+* HTML parsing is now provided by `net.sourceforge.htmlunit:neko-htmlunit:2.61.0` (previously Nokogiri used a fork of `org.cyberneko.html:nekohtml`)
+* Vendored Jing is updated from `com.thaiopensource:jing:20091111` to `nu.validator:jing:20200702VNU`.
+* New dependency on `net.sf.saxon:Saxon-HE:9.6.0-4` (via `nu.validator:jing:20200702VNU`).
+
+
+### Added
+
+* `Node#wrap` and `NodeSet#wrap` now also accept a `Node` type argument, which will be `dup`ed for each wrapper. For cases where many nodes are being wrapped, creating a `Node` once using `Document#create_element` and passing that `Node` multiple times is significantly faster than re-parsing markup on each call. [[#2657](https://github.com/sparklemotion/nokogiri/issues/2657)]
+* [CRuby] Invocation of custom XPath or CSS handler functions may now use the `nokogiri` namespace prefix. Historically, the JRuby implementation _required_ this namespace but the CRuby implementation did not support it. It's recommended that all XPath and CSS queries use the `nokogiri` namespace going forward. Invocation without the namespace is planned for deprecation in v1.15.0 and removal in a future release. [[#2147](https://github.com/sparklemotion/nokogiri/issues/2147)]
+* `HTML5::Document#quirks_mode` and `HTML5::DocumentFragment#quirks_mode` expose the quirks mode used by the parser.
+
+
+### Improved
+
+#### Functional
+
+* HTML5 parser update to reflect changes to the living specification:
+ * [Add the <search> element by domenic · whatwg/html](https://github.com/whatwg/html/pull/7320)
+ * [Remove parse error for <template><tr></tr> </template> by zcorpan · whatwg/html](https://github.com/whatwg/html/pull/8271)
+
+#### Performance
+
+* Serialization of HTML5 documents and fragments has been re-implemented and is ~10x faster than previous versions. [[#2596](https://github.com/sparklemotion/nokogiri/issues/2596), [#2569](https://github.com/sparklemotion/nokogiri/issues/2569)]
+* Parsing of HTML5 documents is ~90% faster thanks to additional compiler optimizations being applied. [[#2639](https://github.com/sparklemotion/nokogiri/issues/2639)]
+* Compare `Encoding` objects rather than compare their names. This is a slight performance improvement and is future-proof. [[#2454](https://github.com/sparklemotion/nokogiri/issues/2454)] (Thanks, [@casperisfine](https://github.com/casperisfine)!)
+
+#### Error handling
+
+* `Document#canonicalize` now raises an exception if `inclusive_namespaces` is non-nil and the mode is inclusive, i.e. `XML_C14N_1_0` or `XML_C14N_1_1`. `inclusive_namespaces` can only be passed with exclusive modes, and previously this silently failed.
+* Empty CSS selectors now raise a clearer `Nokogiri::CSS::SyntaxError` message, "empty CSS selector". Previously the exception raised from the bowels of `racc` was "unexpected '$' after ''". [[#2700](https://github.com/sparklemotion/nokogiri/issues/2700)]
+* [CRuby] `XML::Reader` parsing errors encountered during `Reader#attribute_hash` and `Reader#namespaces` now raise an `XML::SyntaxError`. Previously these methods would return `nil` and users would generally experience `NoMethodErrors` from elsewhere in the code.
+* Prefer `ruby_xmalloc` to `malloc` within the C extension. [[#2480](https://github.com/sparklemotion/nokogiri/issues/2480)] (Thanks, [@Garfield96](https://github.com/Garfield96)!)
+
+#### Installation
+
+* Avoid compile-time conflict with system-installed `gumbo.h` on OpenBSD. [[#2464](https://github.com/sparklemotion/nokogiri/issues/2464)]
+* Remove calls to `vasprintf` in favor of platform-independent `rb_vsprintf`
+* Installation from source on systems missing libiconv will once again generate a helpful error message (broken since v1.11.0). [[#2505](https://github.com/sparklemotion/nokogiri/issues/2505)]
+* [CRuby+OSX] Compiling from source on MacOS will use the clang option `-Wno-unknown-warning-option` to avoid errors when Ruby injects options that clang doesn't know about. [[#2689](https://github.com/sparklemotion/nokogiri/issues/2689)]
+
+
+### Fixed
+
+* `SAX::Parser`'s `encoding` attribute will not be clobbered when an alternative encoding is passed into `SAX::Parser#parse_io`. [[#1942](https://github.com/sparklemotion/nokogiri/issues/1942)] (Thanks, [@kp666](https://github.com/kp666)!)
+* Serialized `HTML4::DocumentFragment` will now be properly encoded. Previously this empty string was encoded as `US-ASCII`. [[#2649](https://github.com/sparklemotion/nokogiri/issues/2649)]
+* `Node#wrap` now uses the parent as the context node for parsing wrapper markup, falling back to the document for unparented nodes. Previously the document was always used.
+* [CRuby] UTF-16-encoded documents longer than ~4000 code points now serialize properly. Previously the serialized document was corrupted when it exceeded the length of libxml2's internal string buffer. [[#752](https://github.com/sparklemotion/nokogiri/issues/752)]
+* [CRuby] The HTML5 parser now correctly handles text at the end of `form` elements.
+* [CRuby] `HTML5::Document#fragment` now always uses `body` as the parsing context. Previously, fragments were parsed in the context of the associated document's root node, which allowed for inconsistent parsing. [[#2553](https://github.com/sparklemotion/nokogiri/issues/2553)]
+* [CRuby] `Nokogiri::HTML5::Document#url` now correctly returns the URL passed to the constructor method. Previously it always returned `nil`. [[#2583](https://github.com/sparklemotion/nokogiri/issues/2583)]
+* [CRuby] `HTML5` encoding detection is now case-insensitive with respect to `meta` tag charset declaration. [[#2693](https://github.com/sparklemotion/nokogiri/issues/2693)]
+* [CRuby] `HTML5` fragment parsing in context of an annotation-xml node now works. Previously this rarely-used path invoked rb_funcall with incorrect parameters, resulting in an exception, a fatal error, or potentially a segfault. [[#2692](https://github.com/sparklemotion/nokogiri/issues/2692)]
+* [CRuby] `HTML5` quirks mode during fragment parsing more closely matches document parsing. [[#2646](https://github.com/sparklemotion/nokogiri/issues/2646)]
+* [JRuby] Fixed a bug with adding the same namespace to multiple nodes via `#add_namespace_definition`. [[#1247](https:/github.com/sparklemotion/nokogiri/issues/1247)]
+* [JRuby] `NodeSet#[]` now raises a TypeError if passed an invalid parameter type. [[#2211](https://github.com/sparklemotion/nokogiri/issues/2211)]
+
+
+### Deprecated
+
+* `Nokogiri.install_default_aliases` is deprecated in favor of `Nokogiri::EncodingHandler.install_default_aliases`. This is part of a private API and is probably not called by anybody, but we'll go through a deprecation cycle before removal anyway. [[#2643](https://github.com/sparklemotion/nokogiri/issues/2643), [#2446](https://github.com/sparklemotion/nokogiri/issues/2446)]
+
+
+### Changed
+
+* [CRuby+OSX] Technical note: On MacOS Ruby 3.2, the symbols from libxml2 and libxslt are no longer exported. Ruby 3.2 adopted new features from the Darwin toolchain that make it challenging to continue to support this rarely-used binary API. A future minor release of Nokogiri may remove these symbols (and others) entirely. Feedback from downstream gem maintainers is welcome at [#2746](https://github.com/sparklemotion/nokogiri/issues/2746), where you'll also be able to read deeper context on this decision.
+
+
+### Thank you!
+
+The following people and organizations were kind enough to sponsor [@flavorjones](https://github.com/flavorjones) or the Nokogiri project during the development of v1.14.0:
+
+* Götz Görisch [@GoetzGoerisch](https://github.com/GoetzGoerisch)
+* Airbnb [@airbnb](https://github.com/airbnb)
+* Kyohei Nanba [@kyo-nanba](https://github.com/kyo-nanba)
+* Maxime Gauthier [@biximilien](https://github.com/biximilien)
+* [@renuo](https://github.com/renuo)
+* [@dbootyfvrt](https://github.com/dbootyfvrt)
+* YOSHIDA Katsuhiko [@kyoshidajp](https://github.com/kyoshidajp)
+* Homebrew [@Homebrew](https://github.com/Homebrew)
+* David Vrensk [@dvrensk](https://github.com/dvrensk)
+* Alex Daragiu [@daragiu](https://github.com/daragiu)
+* Github [@github](https://github.com/github)
+* Julian Joseph [@Julian88Tex](https://github.com/Julian88Tex)
+* Charles Simon-Meunier [@csimonmeunier](https://github.com/csimonmeunier)
+* Ben Slaughter [@benSlaughter](https://github.com/benSlaughter)
+* Garen Torikian [@gjtorikian](https://github.com/gjtorikian)
+* Frank Groeneveld [@frenkel](https://github.com/frenkel)
+* Hiroshi SHIBATA [@hsbt](https://github.com/hsbt)
+
+
+## 1.13.10 / 2022-12-07
+
+### Security
+
+* [CRuby] Address CVE-2022-23476, unchecked return value from `xmlTextReaderExpand`. See [GHSA-qv4q-mr5r-qprj](https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-qv4q-mr5r-qprj) for more information.
+
+
+### Improvements
+
+* [CRuby] `XML::Reader#attribute_hash` now returns `nil` on parse errors. This restores the behavior of `#attributes` from v1.13.7 and earlier. [[#2715](https://github.com/sparklemotion/nokogiri/issues/2715)]
+
+
+## 1.13.9 / 2022-10-18
+
+### Security
+
+* [CRuby] Vendored libxml2 is updated to address [CVE-2022-2309](https://nvd.nist.gov/vuln/detail/CVE-2022-2309), [CVE-2022-40304](https://nvd.nist.gov/vuln/detail/CVE-2022-40304), and [CVE-2022-40303](https://nvd.nist.gov/vuln/detail/CVE-2022-40303). See [GHSA-2qc6-mcvw-92cw](https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-2qc6-mcvw-92cw) for more information.
+* [CRuby] Vendored zlib is updated to address [CVE-2022-37434](https://ubuntu.com/security/CVE-2022-37434). Nokogiri was not affected by this vulnerability, but this version of zlib was being flagged up by some vulnerability scanners, see [#2626](https://github.com/sparklemotion/nokogiri/issues/2626) for more information.
+
+
+### Dependencies
+
+* [CRuby] Vendored libxml2 is updated to [v2.10.3](https://gitlab.gnome.org/GNOME/libxml2/-/releases/v2.10.3) from v2.9.14.
+* [CRuby] Vendored libxslt is updated to [v1.1.37](https://gitlab.gnome.org/GNOME/libxslt/-/releases/v1.1.37) from v1.1.35.
+* [CRuby] Vendored zlib is updated from 1.2.12 to 1.2.13. (See [LICENSE-DEPENDENCIES.md](https://github.com/sparklemotion/nokogiri/blob/v1.13.x/LICENSE-DEPENDENCIES.md#platform-releases) for details on which packages redistribute this library.)
+
+
+### Fixed
+
+* [CRuby] `Nokogiri::XML::Namespace` objects, when compacted, update their internal struct's reference to the Ruby object wrapper. Previously, with GC compaction enabled, a segmentation fault was possible after compaction was triggered. [[#2658](https://github.com/sparklemotion/nokogiri/issues/2658)] (Thanks, [@eightbitraptor](https://github.com/eightbitraptor) and [@peterzhu2118](https://github.com/peterzhu2118)!)
+* [CRuby] `Document#remove_namespaces!` now defers freeing the underlying `xmlNs` struct until the `Document` is GCed. Previously, maintaining a reference to a `Namespace` object that was removed in this way could lead to a segfault. [[#2658](https://github.com/sparklemotion/nokogiri/issues/2658)]
+
+
+## 1.13.8 / 2022-07-23
+
+### Deprecated
+
+* `XML::Reader#attribute_nodes` is deprecated due to incompatibility between libxml2's `xmlReader` memory semantics and Ruby's garbage collector. Although this method continues to exist for backwards compatibility, it is unsafe to call and may segfault. This method will be removed in a future version of Nokogiri, and callers should use `#attribute_hash` instead. [[#2598](https://github.com/sparklemotion/nokogiri/issues/2598)]
+
+
+### Improvements
+
+* `XML::Reader#attribute_hash` is a new method to safely retrieve the attributes of a node from `XML::Reader`. [[#2598](https://github.com/sparklemotion/nokogiri/issues/2598), [#2599](https://github.com/sparklemotion/nokogiri/issues/2599)]
+
+
+### Fixed
+
+* [CRuby] Calling `XML::Reader#attributes` is now safe to call. In Nokogiri <= 1.13.7 this method may segfault. [[#2598](https://github.com/sparklemotion/nokogiri/issues/2598), [#2599](https://github.com/sparklemotion/nokogiri/issues/2599)]
+
+
+## 1.13.7 / 2022-07-12
+
+### Fixed
+
+`XML::Node` objects, when compacted, update their internal struct's reference to the Ruby object wrapper. Previously, with GC compaction enabled, a segmentation fault was possible after compaction was triggered. [[#2578](https://github.com/sparklemotion/nokogiri/issues/2578)] (Thanks, [@eightbitraptor](https://github.com/eightbitraptor)!)
+
+
+## 1.13.6 / 2022-05-08
+
+### Security
+
+* [CRuby] Address [CVE-2022-29181](https://nvd.nist.gov/vuln/detail/CVE-2022-29181), improper handling of unexpected data types, related to untrusted inputs to the SAX parsers. See [GHSA-xh29-r2w5-wx8m](https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-xh29-r2w5-wx8m) for more information.
+
+
+### Improvements
+
+* `{HTML4,XML}::SAX::{Parser,ParserContext}` constructor methods now raise `TypeError` instead of segfaulting when an incorrect type is passed.
+
+
+## 1.13.5 / 2022-05-04
+
+### Security
+
+* [CRuby] Vendored libxml2 is updated to address [CVE-2022-29824](https://nvd.nist.gov/vuln/detail/CVE-2022-29824). See [GHSA-cgx6-hpwq-fhv5](https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-cgx6-hpwq-fhv5) for more information.
+
+
+### Dependencies
+
+* [CRuby] Vendored libxml2 is updated from v2.9.13 to [v2.9.14](https://gitlab.gnome.org/GNOME/libxml2/-/releases/v2.9.14).
+
+
+### Improvements
+
+* [CRuby] The libxml2 HTML parser no longer exhibits quadratic behavior when recovering some broken markup related to start-of-tag and bare `<` characters.
+
+
+### Changed
+
+* [CRuby] The libxml2 HTML parser in v2.9.14 recovers from some broken markup differently. Notably, the XML CDATA escape sequence ` 2.6.1` to `~> 2.7.0`. ("ruby" platform gem only.)
+
+
+### Improved
+
+* `{XML,HTML4}::DocumentFragment` constructors all now take an optional parse options parameter or block (similar to Document constructors). [[#1692](https://github.com/sparklemotion/nokogiri/issues/1692)] (Thanks, [@JackMc](https://github.com/JackMc)!)
+* `Nokogiri::CSS.xpath_for` allows an `XPathVisitor` to be injected, for finer-grained control over how CSS queries are translated into XPath.
+* [CRuby] `XML::Reader#encoding` will return the encoding detected by the parser when it's not passed to the constructor. [[#980](https://github.com/sparklemotion/nokogiri/issues/980)]
+* [CRuby] Handle abruptly-closed HTML comments as recommended by WHATWG. (Thanks to [tehryanx](https://hackerone.com/tehryanx?type=user) for reporting!)
+* [CRuby] `Node#line` is no longer capped at 65535. libxml v2.9.0 and later support a new parse option, exposed as `Nokogiri::XML::ParseOptions::PARSE_BIG_LINES`, which is turned on by default in `ParseOptions::DEFAULT_{XML,XSLT,HTML,SCHEMA}` (Note that JRuby already supported large line numbers.) [[#1764](https://github.com/sparklemotion/nokogiri/issues/1764), [#1493](https://github.com/sparklemotion/nokogiri/issues/1493), [#1617](https://github.com/sparklemotion/nokogiri/issues/1617), [#1505](https://github.com/sparklemotion/nokogiri/issues/1505), [#1003](https://github.com/sparklemotion/nokogiri/issues/1003), [#533](https://github.com/sparklemotion/nokogiri/issues/533)]
+* [CRuby] If a cycle is introduced when reparenting a node (i.e., the node becomes its own ancestor), a `RuntimeError` is raised. libxml2 does no checking for this, which means cycles would otherwise result in infinite loops on subsequent operations. (Note that JRuby already did this.) [[#1912](https://github.com/sparklemotion/nokogiri/issues/1912)]
+* [CRuby] Source builds will download zlib and libiconv via HTTPS. ("ruby" platform gem only.) [[#2391](https://github.com/sparklemotion/nokogiri/issues/2391)] (Thanks, [@jmartin-r7](https://github.com/jmartin-r7)!)
+* [JRuby] `Node#line` behavior has been modified to return the line number of the node in the _final DOM structure_. This behavior is different from CRuby, which returns the node's position in the _input string_. Ideally the two implementations would be the same, but at least is now officially documented and tested. The real-world impact of this change is that the value returned in JRuby is greater by 1 to account for the XML prolog in the output. [[#2380](https://github.com/sparklemotion/nokogiri/issues/2380)] (Thanks, [@dabdine](https://github.com/dabdine)!)
+
+
+### Fixed
+
+* CSS queries on HTML5 documents now correctly match foreign elements (SVG, MathML) when namespaces are not specified in the query. [[#2376](https://github.com/sparklemotion/nokogiri/issues/2376)]
+* `XML::Builder` blocks restore context properly when exceptions are raised. [[#2372](https://github.com/sparklemotion/nokogiri/issues/2372)] (Thanks, [@ric2b](https://github.com/ric2b) and [@rinthedev](https://github.com/rinthedev)!)
+* The `Nokogiri::CSS::Parser` cache now uses the `XPathVisitor` configuration as part of the cache key, preventing incorrect cache results from being returned when multiple `XPathVisitor` options are being used.
+* Error recovery from in-context parsing (e.g., `Node#parse`) now always uses the correct `DocumentFragment` class. Previously `Nokogiri::HTML4::DocumentFragment` was always used, even for XML documents. [[#1158](https://github.com/sparklemotion/nokogiri/issues/1158)]
+* `DocumentFragment#>` now works properly, matching a CSS selector against only the fragment roots. [[#1857](https://github.com/sparklemotion/nokogiri/issues/1857)]
+* `XML::DocumentFragment#errors` now correctly contains any parsing errors encountered. Previously this was always empty. (Note that `HTML::DocumentFragment#errors` already did this.)
+* [CRuby] Fix memory leak in `Document#canonicalize` when inclusive namespaces are passed in. [[#2345](https://github.com/sparklemotion/nokogiri/issues/2345)]
+* [CRuby] Fix memory leak in `Document#canonicalize` when an argument type error is raised. [[#2345](https://github.com/sparklemotion/nokogiri/issues/2345)]
+* [CRuby] Fix memory leak in `EncodingHandler` where iconv handlers were not being cleaned up. [[#2345](https://github.com/sparklemotion/nokogiri/issues/2345)]
+* [CRuby] Fix memory leak in XPath custom handlers where string arguments were not being cleaned up. [[#2345](https://github.com/sparklemotion/nokogiri/issues/2345)]
+* [CRuby] Fix memory leak in `Reader#base_uri` where the string returned by libxml2 was not freed. [[#2347](https://github.com/sparklemotion/nokogiri/issues/2347)]
+* [JRuby] Deleting a `Namespace` from a `NodeSet` no longer modifies the `href` to be the default namespace URL.
+* [JRuby] Fix XHTML formatting of closing tags for non-container elements. [[#2355](https://github.com/sparklemotion/nokogiri/issues/2355)]
+
+
+### Deprecated
+
+* Passing a `Nokogiri::XML::Node` as the second parameter to `Node.new` is deprecated and will generate a warning. This parameter should be a kind of `Nokogiri::XML::Document`. This will become an error in a future version of Nokogiri. [[#975](https://github.com/sparklemotion/nokogiri/issues/975)]
+* `Nokogiri::CSS::Parser`, `Nokogiri::CSS::Tokenizer`, and `Nokogiri::CSS::Node` are now internal-only APIs that are no longer documented, and should not be considered stable. With the introduction of `XPathVisitor` injection into `Nokogiri::CSS.xpath_for` there should be no reason to rely on these internal APIs.
+* CSS-to-XPath utility classes `Nokogiri::CSS::XPathVisitorAlwaysUseBuiltins` and `XPathVisitorOptimallyUseBuiltins` are deprecated. Prefer `Nokogiri::CSS::XPathVisitor` with appropriate constructor arguments. These classes will be removed in a future version of Nokogiri.
+
+
+## 1.12.5 / 2021-09-27
+
+### Security
+
+[JRuby] Address CVE-2021-41098 ([GHSA-2rr5-8q37-2w7h](https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-2rr5-8q37-2w7h)).
+
+In Nokogiri v1.12.4 and earlier, on JRuby only, the SAX parsers resolve external entities (XXE) by default. This fix turns off entity-resolution-by-default in the JRuby SAX parsers to match the CRuby SAX parsers' behavior.
+
+CRuby users are not affected by this CVE.
+
+
+### Fixed
+
+* [CRuby] `Document#to_xhtml` properly serializes self-closing tags in libxml > 2.9.10. A behavior change introduced in libxml 2.9.11 resulted in emitting start and and tags (e.g., ` `) instead of a self-closing tag (e.g., ` `) in previous Nokogiri versions. [[#2324](https://github.com/sparklemotion/nokogiri/issues/2324)]
+
+
+## 1.12.4 / 2021-08-29
+
+### Notable fix: Namespace inheritance
+
+Namespace behavior when reparenting nodes has historically been poorly specified and the behavior diverged between CRuby and JRuby. As a result, making this behavior consistent in v1.12.0 introduced a breaking change.
+
+This patch release reverts the Builder behavior present in v1.12.0..v1.12.3 but keeps the Document behavior. This release also introduces a Document attribute to allow affected users to easily change this behavior for their legacy code without invasive changes.
+
+
+#### Compensating Feature in XML::Document
+
+This release of Nokogiri introduces a new `Document` boolean attribute, `namespace_inheritance`, which controls whether children should inherit a namespace when they are reparented. `Nokogiri::XML:Document` defaults this attribute to `false` meaning "do not inherit," thereby making explicit the behavior change introduced in v1.12.0.
+
+CRuby users who desire the pre-v1.12.0 behavior may set `document.namespace_inheritance = true` before reparenting nodes.
+
+See https://nokogiri.org/rdoc/Nokogiri/XML/Document.html#namespace_inheritance-instance_method for example usage.
+
+
+#### Fix for XML::Builder
+
+However, recognizing that we want `Builder`-created children to inherit namespaces, Builder now will set `namespace_inheritance=true` on the underlying document for both JRuby and CRuby. This means that, on CRuby, the pre-v1.12.0 behavior is restored.
+
+Users who want to turn this behavior off may pass a keyword argument to the Builder constructor like so:
+
+``` ruby
+Nokogiri::XML::Builder.new(namespace_inheritance: false)
+```
+
+See https://nokogiri.org/rdoc/Nokogiri/XML/Builder.html#label-Namespace+inheritance for example usage.
+
+
+#### Downstream gem maintainers
+
+Note that any downstream gems may want to specifically omit Nokogiri v1.12.0--v1.12.3 from their dependency specification if they rely on child namespace inheritance:
+
+``` ruby
+Gem::Specification.new do |gem|
+ # ...
+ gem.add_runtime_dependency 'nokogiri', '!=1.12.3', '!=1.12.2', '!=1.12.1', '!=1.12.0'
+ # ...
+end
+```
+
+
+### Fixed
+
+* [JRuby] Fix NPE in Schema parsing when an imported resource doesn't have a `systemId`. [[#2296](https://github.com/sparklemotion/nokogiri/issues/2296)] (Thanks, [@pepijnve](https://github.com/pepijnve)!)
+
+
+## 1.12.3 / 2021-08-10
+
+### Fixed
+
+* [CRuby] Fix compilation of libgumbo on older systems with versions of GCC that give errors on C99-isms. Affected systems include RHEL6, RHEL7, and SLES12. [[#2302](https://github.com/sparklemotion/nokogiri/issues/2302)]
+
+
+## 1.12.2 / 2021-08-04
+
+### Fixed
+
+* [CRuby] Ensure that C extension files in non-native gem installations are loaded using `require` and rely on `$LOAD_PATH` instead of using `require_relative`. This issue only exists when deleting shared libraries that exist outside the extensions directory, something users occasionally do to conserve disk space. [[#2300](https://github.com/sparklemotion/nokogiri/issues/2300)]
+
+
+## 1.12.1 / 2021-08-03
+
+### Fixed
+
+* [CRuby] Fix compilation of libgumbo on BSD systems by avoiding GNU-isms. [[#2298](https://github.com/sparklemotion/nokogiri/issues/2298)]
+
+
+## 1.12.0 / 2021-08-02
+
+### Notable Addition: HTML5 Support (CRuby only)
+
+__HTML5 support__ has been added (to CRuby only) by merging [Nokogumbo](https://github.com/rubys/nokogumbo) into Nokogiri. The Nokogumbo public API has been preserved, so this functionality is available under the `Nokogiri::HTML5` namespace. [[#2204](https://github.com/sparklemotion/nokogiri/issues/2204)]
+
+Please note that HTML5 support is not available for JRuby in this version. However, we feel it is important to think about JRuby and we hope to work on this in the future. If you're interested in helping with HTML5 support on JRuby, please reach out to the maintainers by commenting on issue [#2227](https://github.com/sparklemotion/nokogiri/issues/2227).
+
+Many thanks to Sam Ruby, Steve Checkoway, and Craig Barnes for creating and maintaining Nokogumbo and supporting the Gumbo HTML5 parser. They're now Nokogiri core contributors with all the powers and privileges pertaining thereto. 🙌
+
+
+### Notable Change: `Nokogiri::HTML4` module and namespace
+
+`Nokogiri::HTML` has been renamed to `Nokogiri::HTML4`, and `Nokogiri::HTML` is aliased to preserve backwards-compatibility. `Nokogiri::HTML` and `Nokogiri::HTML4` parse methods still use libxml2's (or NekoHTML's) HTML4 parser in the v1.12 release series.
+
+Take special note that if you rely on the class name of an object in your code, objects will now report a class of `Nokogiri::HTML4::Foo` where they previously reported `Nokogiri::HTML::Foo`. Instead of relying on the string returned by `Object#class`, prefer `Class#===` or `Object#is_a?` or `Object#instance_of?`.
+
+Future releases of Nokogiri may deprecate `HTML` methods or otherwise change this behavior, so please start using `HTML4` in place of `HTML`.
+
+
+### Added
+
+* [CRuby] `Nokogiri::VERSION_INFO["libxslt"]["datetime_enabled"]` is a new boolean value which describes whether libxslt (or, more properly, libexslt) has compiled-in datetime support. This generally going to be `true`, but some distros ship without this support (e.g., some mingw UCRT-based packages, see https://github.com/msys2/MINGW-packages/pull/8957). See [#2272](https://github.com/sparklemotion/nokogiri/issues/2272) for more details.
+
+
+### Changed
+
+* Introduce a new constant, `Nokogiri::XML::ParseOptions::DEFAULT_XSLT`, which adds the libxslt-preferred options of `NOENT | DTDLOAD | DTDATTR | NOCDATA` to `ParseOptions::DEFAULT_XML`.
+* `Nokogiri.XSLT` parses stylesheets using `ParseOptions::DEFAULT_XSLT`, which should make some edge-case XSL transformations match libxslt's default behavior. [[#1940](https://github.com/sparklemotion/nokogiri/issues/1940)]
+
+
+### Fixed
+
+* [CRuby] Namespaced attributes are handled properly when their parent node is reparented into another document. Previously, the namespace may have gotten dropped. [[#2228](https://github.com/sparklemotion/nokogiri/issues/2228)]
+* [CRuby] Reparented nodes no longer inherit their parent's namespace. Previously, a node without a namespace was forced to adopt its parent's namespace. [[#1712](https://github.com/sparklemotion/nokogiri/issues/1712), [#425](https://github.com/sparklemotion/nokogiri/issues/425)]
+
+
+### Improved
+
+* [CRuby] Speed up (slightly) the compile time of packaged libraries `libiconv`, `libxml2`, and `libxslt` by using autoconf's `--disable-dependency-tracking` option. ("ruby" platform gem only.)
+
+
+### Deprecated
+
+* Deprecating Nokogumbo's `Nokogiri::HTML5.get`. This method will be removed in a future version of Nokogiri.
+
+
+### Dependencies
+
+* [CRuby] Upgrade mini_portile2 dependency from `~> 2.5.0` to `~> 2.6.1`. ("ruby" platform gem only.)
+
+
+## 1.11.7 / 2021-06-02
+
+### Fixed
+
+* [CRuby] Backporting an upstream fix to XPath recursion depth limits which impacted some users of complex XPath queries. This issue is present in libxml 2.9.11 and 2.9.12. [[#2257](https://github.com/sparklemotion/nokogiri/issues/2257)]
+
+
+## 1.11.6 / 2021-05-26
+
+### Fixed
+
+* [CRuby] `DocumentFragment#path` now does proper error-checking to handle behavior introduced in libxml > 2.9.10. In v1.11.4 and v1.11.5, calling `DocumentFragment#path` could result in a segfault.
+
+
+## 1.11.5 / 2021-05-19
+
+### Fixed
+
+[Windows CRuby] Work around segfault at process exit on Windows when using libxml2 system DLLs.
+
+libxml 2.9.12 introduced new behavior to avoid memory leaks when unloading libxml2 shared libraries (see [libxml/!66](https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/66)). Early testing caught this segfault on non-Windows platforms (see [#2059](https://github.com/sparklemotion/nokogiri/issues/2059) and [libxml@956534e](https://gitlab.gnome.org/GNOME/libxml2/-/commit/956534e02ef280795a187c16f6ac04e107f23c5d)) but it was incompletely fixed and is still an issue on Windows platforms that are using system DLLs.
+
+We work around this by configuring libxml2 in this situation to use its default memory management functions. Note that if Nokogiri is not on Windows, or is not using shared system libraries, it will will continue to configure libxml2 to use Ruby's memory management functions. `Nokogiri::VERSION_INFO["libxml"]["memory_management"]` will allow you to verify when the default memory management functions are being used. [[#2241](https://github.com/sparklemotion/nokogiri/issues/2241)]
+
+
+### Added
+
+`Nokogiri::VERSION_INFO["libxml"]` now contains the key `"memory_management"` to declare whether libxml2 is using its `default` memory management functions, or whether it uses the memory management functions from `ruby`. See above for more details.
+
+
+## 1.11.4 / 2021-05-14
+
+### Security
+
+[CRuby] Vendored libxml2 upgraded to v2.9.12 which addresses:
+
+* [CVE-2019-20388](https://security.archlinux.org/CVE-2019-20388)
+* [CVE-2020-24977](https://security.archlinux.org/CVE-2020-24977)
+* [CVE-2021-3517](https://security.archlinux.org/CVE-2021-3517)
+* [CVE-2021-3518](https://security.archlinux.org/CVE-2021-3518)
+* [CVE-2021-3537](https://security.archlinux.org/CVE-2021-3537)
+* [CVE-2021-3541](https://security.archlinux.org/CVE-2021-3541)
+
+Note that two additional CVEs were addressed upstream but are not relevant to this release. [CVE-2021-3516](https://security.archlinux.org/CVE-2021-3516) via `xmllint` is not present in Nokogiri, and [CVE-2020-7595](https://security.archlinux.org/CVE-2020-7595) has been patched in Nokogiri since v1.10.8 (see [#1992](https://github.com/sparklemotion/nokogiri/issues/1992)).
+
+Please see [nokogiri/GHSA-7rrm-v45f-jp64 ](https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-7rrm-v45f-jp64) or [#2233](https://github.com/sparklemotion/nokogiri/issues/2233) for a more complete analysis of these CVEs and patches.
+
+
+### Dependencies
+
+* [CRuby] vendored libxml2 is updated from 2.9.10 to 2.9.12. (Note that 2.9.11 was skipped because it was superseded by 2.9.12 a few hours after its release.)
+
+
+## 1.11.3 / 2021-04-07
+
+### Fixed
+
+* [CRuby] Passing non-`Node` objects to `Document#root=` now raises an `ArgumentError` exception. Previously this likely segfaulted. [[#1900](https://github.com/sparklemotion/nokogiri/issues/1900)]
+* [JRuby] Passing non-`Node` objects to `Document#root=` now raises an `ArgumentError` exception. Previously this raised a `TypeError` exception.
+* [CRuby] arm64/aarch64 systems (like Apple's M1) can now compile libxml2 and libxslt from source (though we continue to strongly advise users to install the native gems for the best possible experience)
+
+
+## 1.11.2 / 2021-03-11
+
+### Fixed
+
+* [CRuby] `NodeSet` may now safely contain `Node` objects from multiple documents. Previously the GC lifecycle of the parent `Document` objects could lead to nodes being GCed while still in scope. [[#1952](https://github.com/sparklemotion/nokogiri/issues/1952#issuecomment-770856928)]
+* [CRuby] Patch libxml2 to avoid "huge input lookup" errors on large CDATA elements. (See upstream [GNOME/libxml2#200](https://gitlab.gnome.org/GNOME/libxml2/-/issues/200) and [GNOME/libxml2!100](https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/100).) [[#2132](https://github.com/sparklemotion/nokogiri/issues/2132)].
+* [CRuby+Windows] Enable Nokogumbo (and other downstream gems) to compile and link against `nokogiri.so` by including `LDFLAGS` in `Nokogiri::VERSION_INFO`. [[#2167](https://github.com/sparklemotion/nokogiri/issues/2167)]
+* [CRuby] `{XML,HTML}::Document.parse` now invokes `#initialize` exactly once. Previously `#initialize` was invoked twice on each object.
+* [JRuby] `{XML,HTML}::Document.parse` now invokes `#initialize` exactly once. Previously `#initialize` was not called, which was a problem for subclassing such as done by `Loofah`.
+
+
+### Improved
+
+* Reduce the number of object allocations needed when parsing an `HTML::DocumentFragment`. [[#2087](https://github.com/sparklemotion/nokogiri/issues/2087)] (Thanks, [@ashmaroli](https://github.com/ashmaroli)!)
+* [JRuby] Update the algorithm used to calculate `Node#line` to be wrong less-often. The underlying parser, Xerces, does not track line numbers, and so we've always used a hacky solution for this method. [[#1223](https://github.com/sparklemotion/nokogiri/issues/1223), [#2177](https://github.com/sparklemotion/nokogiri/issues/2177)]
+* Introduce `--enable-system-libraries` and `--disable-system-libraries` flags to `extconf.rb`. These flags provide the same functionality as `--use-system-libraries` and the `NOKOGIRI_USE_SYSTEM_LIBRARIES` environment variable, but are more idiomatic. [[#2193](https://github.com/sparklemotion/nokogiri/issues/2193)] (Thanks, [@eregon](https://github.com/eregon)!)
+* [TruffleRuby] `--disable-static` is now the default on TruffleRuby when the packaged libraries are used. This is more flexible and compiles faster. (Note, though, that the default on TR is still to use system libraries.) [[#2191](https://github.com/sparklemotion/nokogiri/issues/2191#issuecomment-780724627), [#2193](https://github.com/sparklemotion/nokogiri/issues/2193)] (Thanks, [@eregon](https://github.com/eregon)!)
+
+
+### Changed
+
+* `Nokogiri::XML::Path` is now a Module (previously it has been a Class). It has been acting solely as a Module since v1.0.0. See [8461c74](https://github.com/sparklemotion/nokogiri/commit/8461c74).
+
+
+## 1.11.1 / 2021-01-06
+
+### Fixed
+
+* [CRuby] If `libxml-ruby` is loaded before `nokogiri`, the SAX and Push parsers no longer call `libxml-ruby`'s handlers. Instead, they defensively override the libxml2 global handler before parsing. [[#2168](https://github.com/sparklemotion/nokogiri/issues/2168)]
+
+
+## 1.11.0 / 2021-01-03
+
+### Notes
+
+#### Faster, more reliable installation: Native Gems for Linux and OSX/Darwin
+
+"Native gems" contain pre-compiled libraries for a specific machine architecture. On supported platforms, this removes the need for compiling the C extension and the packaged libraries. This results in **much faster installation** and **more reliable installation**, which as you probably know are the biggest headaches for Nokogiri users.
+
+We've been shipping native Windows gems since 2009, but starting in v1.11.0 we are also shipping native gems for these platforms:
+
+* Linux: `x86-linux` and `x86_64-linux` -- including musl platforms like alpine
+* OSX/Darwin: `x86_64-darwin` and `arm64-darwin`
+
+We'd appreciate your thoughts and feedback on this work at [#2075](https://github.com/sparklemotion/nokogiri/issues/2075).
+
+
+### Dependencies
+
+#### Ruby
+
+This release introduces support for Ruby 2.7 and 3.0 in the precompiled native gems.
+
+This release ends support for:
+
+* Ruby 2.3, for which [official support ended on 2019-03-31](https://www.ruby-lang.org/en/news/2019/03/31/support-of-ruby-2-3-has-ended/) [[#1886](https://github.com/sparklemotion/nokogiri/issues/1886)] (Thanks [@ashmaroli](https://github.com/ashmaroli)!)
+* Ruby 2.4, for which [official support ended on 2020-04-05](https://www.ruby-lang.org/en/news/2020/04/05/support-of-ruby-2-4-has-ended/)
+* JRuby 9.1, which is the Ruby 2.3-compatible release.
+
+
+#### Gems
+
+* Explicitly add racc as a runtime dependency. [[#1988](https://github.com/sparklemotion/nokogiri/issues/1988)] (Thanks, [@voxik](https://github.com/voxik)!)
+* [MRI] Upgrade mini_portile2 dependency from `~> 2.4.0` to `~> 2.5.0` [[#2005](https://github.com/sparklemotion/nokogiri/issues/2005)] (Thanks, [@alejandroperea](https://github.com/alejandroperea)!)
+
+
+### Security
+
+See note below about CVE-2020-26247 in the "Changed" subsection entitled "XML::Schema parsing treats input as untrusted by default".
+
+
+### Added
+
+* Add Node methods for manipulating "keyword attributes" (for example, `class` and `rel`): `#kwattr_values`, `#kwattr_add`, `#kwattr_append`, and `#kwattr_remove`. [[#2000](https://github.com/sparklemotion/nokogiri/issues/2000)]
+* Add support for CSS queries `a:has(> b)`, `a:has(~ b)`, and `a:has(+ b)`. [[#688](https://github.com/sparklemotion/nokogiri/issues/688)] (Thanks, [@jonathanhefner](https://github.com/jonathanhefner)!)
+* Add `Node#value?` to better match expected semantics of a Hash-like object. [[#1838](https://github.com/sparklemotion/nokogiri/issues/1838), [#1840](https://github.com/sparklemotion/nokogiri/issues/1840)] (Thanks, [@MatzFan](https://github.com/MatzFan)!)
+* [CRuby] Add `Nokogiri::XML::Node#line=` for use by downstream libs like nokogumbo. [[#1918](https://github.com/sparklemotion/nokogiri/issues/1918)] (Thanks, [@stevecheckoway](https://github.com/stevecheckoway)!)
+* `nokogiri.gemspec` is back after a 10-year hiatus. We still prefer you use the official releases, but `main` is pretty stable these days, and YOLO.
+
+
+### Performance
+
+* [CRuby] The CSS `~=` operator and class selector `.` are about 2x faster. [[#2137](https://github.com/sparklemotion/nokogiri/issues/2137), [#2135](https://github.com/sparklemotion/nokogiri/issues/2135)]
+* [CRuby] Patch libxml2 to call `strlen` from `xmlStrlen` rather than the naive implementation, because `strlen` is generally optimized for the architecture. [[#2144](https://github.com/sparklemotion/nokogiri/issues/2144)] (Thanks, [@ilyazub](https://github.com/ilyazub)!)
+* Improve performance of some namespace operations. [[#1916](https://github.com/sparklemotion/nokogiri/issues/1916)] (Thanks, [@ashmaroli](https://github.com/ashmaroli)!)
+* Remove unnecessary array allocations from Node serialization methods [[#1911](https://github.com/sparklemotion/nokogiri/issues/1911)] (Thanks, [@ashmaroli](https://github.com/ashmaroli)!)
+* Avoid creation of unnecessary zero-length String objects. [[#1970](https://github.com/sparklemotion/nokogiri/issues/1970)] (Thanks, [@ashmaroli](https://github.com/ashmaroli)!)
+* Always compile libxml2 and libxslt with '-O2' [[#2022](https://github.com/sparklemotion/nokogiri/issues/2022), [#2100](https://github.com/sparklemotion/nokogiri/issues/2100)] (Thanks, [@ilyazub](https://github.com/ilyazub)!)
+* [JRuby] Lots of code cleanup and performance improvements. [[#1934](https://github.com/sparklemotion/nokogiri/issues/1934)] (Thanks, [@kares](https://github.com/kares)!)
+* [CRuby] `RelaxNG.from_document` no longer leaks memory. [[#2114](https://github.com/sparklemotion/nokogiri/issues/2114)]
+
+
+### Improved
+
+* [CRuby] Handle incorrectly-closed HTML comments as WHATWG recommends for browsers. [[#2058](https://github.com/sparklemotion/nokogiri/issues/2058)] (Thanks to HackerOne user [mayflower](https://hackerone.com/mayflower?type=user) for reporting this!)
+* `{HTML,XML}::Document#parse` now accept `Pathname` objects. Previously this worked only if the referenced file was less than 4096 bytes long; longer files resulted in undefined behavior because the `read` method would be repeatedly invoked. [[#1821](https://github.com/sparklemotion/nokogiri/issues/1821), [#2110](https://github.com/sparklemotion/nokogiri/issues/2110)] (Thanks, [@doriantaylor](https://github.com/doriantaylor) and [@phokz](https://github.com/phokz)!)
+* [CRuby] Nokogumbo builds faster because it can now use header files provided by Nokogiri. [[#1788](https://github.com/sparklemotion/nokogiri/issues/1788)] (Thanks, [@stevecheckoway](https://github.com/stevecheckoway)!)
+* Add `frozen_string_literal: true` magic comment to all `lib` files. [[#1745](https://github.com/sparklemotion/nokogiri/issues/1745)] (Thanks, [@oniofchaos](https://github.com/oniofchaos)!)
+* [JRuby] Clean up deprecated calls into JRuby. [[#2027](https://github.com/sparklemotion/nokogiri/issues/2027)] (Thanks, [@headius](https://github.com/headius)!)
+
+
+### Fixed
+
+* HTML Parsing in "strict" mode (i.e., the `RECOVER` parse option not set) now correctly raises a `XML::SyntaxError` exception. Previously the value of the `RECOVER` bit was being ignored by CRuby and was misinterpreted by JRuby. [[#2130](https://github.com/sparklemotion/nokogiri/issues/2130)]
+* The CSS `~=` operator now correctly handles non-space whitespace in the `class` attribute. commit e45dedd
+* The switch to turn off the CSS-to-XPath cache is now thread-local, rather than being shared mutable state. [[#1935](https://github.com/sparklemotion/nokogiri/issues/1935)]
+* The Node methods `add_previous_sibling`, `previous=`, `before`, `add_next_sibling`, `next=`, `after`, `replace`, and `swap` now correctly use their parent as the context node for parsing markup. These methods now also raise a `RuntimeError` if they are called on a node with no parent. [[nokogumbo#160](https://github.com/rubys/nokogumbo/issues/160)]
+* [JRuby] `XML::Schema` XSD validation errors are captured in `XML::Schema#errors`. These errors were previously ignored.
+* [JRuby] Standardize reading from IO like objects, including StringIO. [[#1888](https://github.com/sparklemotion/nokogiri/issues/1888), [#1897](https://github.com/sparklemotion/nokogiri/issues/1897)]
+* [JRuby] Fix how custom XPath function namespaces are inferred to be less naive. [[#1890](https://github.com/sparklemotion/nokogiri/issues/1890), [#2148](https://github.com/sparklemotion/nokogiri/issues/2148)]
+* [JRuby] Clarify exception message when custom XPath functions can't be resolved.
+* [JRuby] Comparison of Node to Document with `Node#<=>` now matches CRuby/libxml2 behavior.
+* [CRuby] Syntax errors are now correctly captured in `Document#errors` for short HTML documents. Previously the SAX parser used for encoding detection was clobbering libxml2's global error handler.
+* [CRuby] Fixed installation on AIX with respect to `vasprintf`. [[#1908](https://github.com/sparklemotion/nokogiri/issues/1908)]
+* [CRuby] On some platforms, avoid symbol name collision with glibc's `canonicalize`. [[#2105](https://github.com/sparklemotion/nokogiri/issues/2105)]
+* [Windows Visual C++] Fixed compiler warnings and errors. [[#2061](https://github.com/sparklemotion/nokogiri/issues/2061), [#2068](https://github.com/sparklemotion/nokogiri/issues/2068)]
+* [CRuby] Fixed Nokogumbo integration which broke in the v1.11.0 release candidates. [[#1788](https://github.com/sparklemotion/nokogiri/issues/1788)] (Thanks, [@stevecheckoway](https://github.com/stevecheckoway)!)
+* [JRuby] Fixed document encoding regression in v1.11.0 release candidates. [[#2080](https://github.com/sparklemotion/nokogiri/issues/2080), [#2083](https://github.com/sparklemotion/nokogiri/issues/2083)] (Thanks, [@thbar](https://github.com/thbar)!)
+
+
+### Removed
+
+* The internal method `Nokogiri::CSS::Parser.cache_on=` has been removed. Use `.set_cache` if you need to muck with the cache internals.
+* The class method `Nokogiri::CSS::Parser.parse` has been removed. This was originally deprecated in 2009 in 13db61b. Use `Nokogiri::CSS.parse` instead.
+
+
+### Changed
+
+#### `XML::Schema` input is now "untrusted" by default
+
+Address [CVE-2020-26247](https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-vr8q-g5c7-m54m).
+
+In Nokogiri versions <= 1.11.0.rc3, XML Schemas parsed by `Nokogiri::XML::Schema` were **trusted** by default, allowing external resources to be accessed over the network, potentially enabling XXE or SSRF attacks.
+
+This behavior is counter to the security policy intended by Nokogiri maintainers, which is to treat all input as **untrusted** by default whenever possible.
+
+Please note that this security fix was pushed into a new minor version, 1.11.x, rather than a patch release to the 1.10.x branch, because it is a breaking change for some schemas and the risk was assessed to be "Low Severity".
+
+More information and instructions for enabling "trusted input" behavior in v1.11.0.rc4 and later is available at the [public advisory](https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-vr8q-g5c7-m54m).
+
+
+#### HTML parser now obeys the `strict` or `norecover` parsing option
+
+(Also noted above in the "Fixed" section) HTML Parsing in "strict" mode (i.e., the `RECOVER` parse option not set) now correctly raises a `XML::SyntaxError` exception. Previously the value of the `RECOVER` bit was being ignored by CRuby and was misinterpreted by JRuby.
+
+If you're using the default parser options, you will be unaffected by this fix. If you're passing `strict` or `norecover` to your HTML parser call, you may be surprised to see that the parser now fails to recover and raises a `XML::SyntaxError` exception. Given the number of HTML documents on the internet that libxml2 would consider to be ill-formed, this is probably not what you want, and you can omit setting that parse option to restore the behavior that you have been relying upon.
+
+Apologies to anyone inconvenienced by this breaking bugfix being present in a minor release, but I felt it was appropriate to introduce this fix because it's straightforward to fix any code that has been relying on this buggy behavior.
+
+
+#### `VersionInfo`, the output of `nokogiri -v`, and related constants
+
+This release changes the metadata provided in `Nokogiri::VersionInfo` which also affects the output of `nokogiri -v`. Some related constants have also been changed. If you're using `VersionInfo` programmatically, or relying on constants related to underlying library versions, please read the detailed changes for `Nokogiri::VersionInfo` at [#2139](https://github.com/sparklemotion/nokogiri/issues/2139) and accept our apologies for the inconvenience.
+
+
+## 1.10.10 / 2020-07-06
+
+### Features
+
+* [MRI] Cross-built Windows gems now support Ruby 2.7 [[#2029](https://github.com/sparklemotion/nokogiri/issues/2029)]. Note that prior to this release, the v1.11.x prereleases provided this support.
+
+
+## 1.10.9 / 2020-03-01
+
+### Fixed
+
+* [MRI] Raise an exception when Nokogiri detects a specific libxml2 edge case involving blank Schema nodes wrapped by Ruby objects that would cause a segfault. Currently no fix is available upstream, so we're preventing a dangerous operation and informing users to code around it if possible. [[#1985](https://github.com/sparklemotion/nokogiri/issues/1985), [#2001](https://github.com/sparklemotion/nokogiri/issues/2001)]
+* [JRuby] Change `NodeSet#to_a` to return a RubyArray instead of Object, for compilation under JRuby 9.2.9 and later. [[#1968](https://github.com/sparklemotion/nokogiri/issues/1968), [#1969](https://github.com/sparklemotion/nokogiri/issues/1969)] (Thanks, [@headius](https://github.com/headius)!)
+
+
+## 1.10.8 / 2020-02-10
+
+### Security
+
+[MRI] Pulled in upstream patch from libxml that addresses CVE-2020-7595. Full details are available in [#1992](https://github.com/sparklemotion/nokogiri/issues/1992). Note that this patch is not yet (as of 2020-02-10) in an upstream release of libxml.
+
+
+## 1.10.7 / 2019-12-03
+
+### Fixed
+
+* [MRI] Ensure the patch applied in v1.10.6 works with GNU `patch`. [[#1954](https://github.com/sparklemotion/nokogiri/issues/1954)]
+
+
+## 1.10.6 / 2019-12-03
+
+### Fixed
+
+* [MRI] Fix FreeBSD installation of vendored libxml2. [[#1941](https://github.com/sparklemotion/nokogiri/issues/1941), [#1953](https://github.com/sparklemotion/nokogiri/issues/1953)] (Thanks, [@nurse](https://github.com/nurse)!)
+
+
+## 1.10.5 / 2019-10-31
+
+### Security
+
+[MRI] Vendored libxslt upgraded to v1.1.34 which addresses three CVEs for libxslt:
+
+* CVE-2019-13117
+* CVE-2019-13118
+* CVE-2019-18197
+* CVE-2019-19956
+
+More details are available at [#1943](https://github.com/sparklemotion/nokogiri/issues/1943).
+
+
+### Dependencies
+
+* [MRI] vendored libxml2 is updated from 2.9.9 to 2.9.10
+* [MRI] vendored libxslt is updated from 1.1.33 to 1.1.34
+
+
+## 1.10.4 / 2019-08-11
+
+### Security
+
+Address CVE-2019-5477 ([#1915](https://github.com/sparklemotion/nokogiri/issues/1915)).
+
+A command injection vulnerability in Nokogiri v1.10.3 and earlier allows commands to be executed in a subprocess by Ruby's `Kernel.open` method. Processes are vulnerable only if the undocumented method `Nokogiri::CSS::Tokenizer#load_file` is being passed untrusted user input.
+
+This vulnerability appears in code generated by the Rexical gem versions v1.0.6 and earlier. Rexical is used by Nokogiri to generate lexical scanner code for parsing CSS queries. The underlying vulnerability was addressed in Rexical v1.0.7 and Nokogiri upgraded to this version of Rexical in Nokogiri v1.10.4.
+
+This CVE's public notice is [#1915](https://github.com/sparklemotion/nokogiri/issues/1915)
+
+
## 1.10.3 / 2019-04-22
-### Security Notes
+### Security
[MRI] Pulled in upstream patch from libxslt that addresses CVE-2019-11068. Full details are available in [#1892](https://github.com/sparklemotion/nokogiri/issues/1892). Note that this patch is not yet (as of 2019-04-22) in an upstream release of libxslt.
@@ -11,91 +800,85 @@
### Security
-* [MRI] Remove support from vendored libxml2 for future script macros. [#1871]
-* [MRI] Remove support from vendored libxml2 for server-side includes within attributes. [#1877]
+* [MRI] Remove support from vendored libxml2 for future script macros. [[#1871](https://github.com/sparklemotion/nokogiri/issues/1871)]
+* [MRI] Remove support from vendored libxml2 for server-side includes within attributes. [[#1877](https://github.com/sparklemotion/nokogiri/issues/1877)]
-### Bug fixes
+### Fixed
-* [JRuby] Fix node ownership in duplicated documents. [#1060]
-* [JRuby] Rethrow exceptions caught by Java SAX handler. [#1847, #1872] (Thanks, @adjam!)
+* [JRuby] Fix node ownership in duplicated documents. [[#1060](https://github.com/sparklemotion/nokogiri/issues/1060)]
+* [JRuby] Rethrow exceptions caught by Java SAX handler. [[#1847](https://github.com/sparklemotion/nokogiri/issues/1847), [#1872](https://github.com/sparklemotion/nokogiri/issues/1872)] (Thanks, [@adjam](https://github.com/adjam)!)
## 1.10.1 / 2019-01-13
-### Features
+### Added
-* [MRI] During installation, handle Xcode 10's new library path. [#1801, #1851] (Thanks, @mlj and @deepj!)
-* Avoid unnecessary creation of `Proc`s in many methods. [#1776] (Thanks, @chopraanmol1!)
+* [MRI] During installation, handle Xcode 10's new library path. [[#1801](https://github.com/sparklemotion/nokogiri/issues/1801), [#1851](https://github.com/sparklemotion/nokogiri/issues/1851)] (Thanks, [@mlj](https://github.com/mlj) and [@deepj](https://github.com/deepj)!)
+* Avoid unnecessary creation of `Proc`s in many methods. [[#1776](https://github.com/sparklemotion/nokogiri/issues/1776)] (Thanks, [@chopraanmol1](https://github.com/chopraanmol1)!)
-### Bug fixes
+### Fixed
-* CSS selector `:has()` now correctly matches against any descendant. Previously this selector matched against only direct children). [#350] (Thanks, @Phrogz!)
+* CSS selector `:has()` now correctly matches against any descendant. Previously this selector matched against only direct children). [[#350](https://github.com/sparklemotion/nokogiri/issues/350)] (Thanks, [@Phrogz](https://github.com/Phrogz)!)
* `NodeSet#attr` now returns `nil` if it's empty. Previously this raised a NoMethodError.
-* [MRI] XPath errors are no longer suppressed during `XSLT::Stylesheet#transform`. Previously these errors were suppressed which led to silent failures and a subsequent segfault. [#1802]
+* [MRI] XPath errors are no longer suppressed during `XSLT::Stylesheet#transform`. Previously these errors were suppressed which led to silent failures and a subsequent segfault. [[#1802](https://github.com/sparklemotion/nokogiri/issues/1802)]
## 1.10.0 / 2019-01-04
-### Features
-
-* [MRI] Cross-built Windows gems now support Ruby 2.6 [#1842, #1850]
-
-
-### Backwards incompatibilities
-
-This release ends support for:
+### Added
-* Ruby 2.2, for which [official support ended on 2018-03-31](https://www.ruby-lang.org/en/news/2018/06/20/support-of-ruby-2-2-has-ended/) [#1841]
-* JRuby 1.7, for which [official support ended on 2017-11-21](https://github.com/jruby/jruby/issues/4112) [#1741]
+* [MRI] Cross-built Windows gems now support Ruby 2.6 [[#1842](https://github.com/sparklemotion/nokogiri/issues/1842), [#1850](https://github.com/sparklemotion/nokogiri/issues/1850)]
### Dependencies
+* This release ends support for Ruby 2.2, for which [official support ended on 2018-03-31](https://www.ruby-lang.org/en/news/2018/06/20/support-of-ruby-2-2-has-ended/) [[#1841](https://github.com/sparklemotion/nokogiri/issues/1841)]
+* This release ends support for JRuby 1.7, for which [official support ended on 2017-11-21](https://github.com/jruby/jruby/issues/4112) [[#1741](https://github.com/sparklemotion/nokogiri/issues/1741)]
* [MRI] libxml2 is updated from 2.9.8 to 2.9.9
* [MRI] libxslt is updated from 1.1.32 to 1.1.33
## 1.9.1 / 2018-12-17
-### Bug fixes
+### Fixed
-* Fix a bug introduced in v1.9.0 where `XML::DocumentFragment#dup` no longer returned an instance of the callee's class, instead always returning an `XML::DocumentFragment`. This notably broke any subclass of `XML::DocumentFragment` including `HTML::DocumentFragment` as well as the Loofah gem's `Loofah::HTML::DocumentFragment`. [#1846]
+* Fix a bug introduced in v1.9.0 where `XML::DocumentFragment#dup` no longer returned an instance of the callee's class, instead always returning an `XML::DocumentFragment`. This notably broke any subclass of `XML::DocumentFragment` including `HTML::DocumentFragment` as well as the Loofah gem's `Loofah::HTML::DocumentFragment`. [[#1846](https://github.com/sparklemotion/nokogiri/issues/1846)]
## 1.9.0 / 2018-12-17
-### Security Notes
+### Security
-* [JRuby] Upgrade Xerces dependency from 2.11.0 to 2.12.0 to address upstream vulnerability CVE-2012-0881 [#1831] (Thanks @grajagandev for reporting.)
+* [JRuby] Upgrade Xerces dependency from 2.11.0 to 2.12.0 to address upstream vulnerability CVE-2012-0881 [[#1831](https://github.com/sparklemotion/nokogiri/issues/1831)] (Thanks [@grajagandev](https://github.com/grajagandev) for reporting.)
-### Notable non-functional changes
+### Improved
-* Decrease installation size by removing many unneeded files (e.g., `/test`) from the packaged gems. [#1719] (Thanks, @stevecrozz!)
+* Decrease installation size by removing many unneeded files (e.g., `/test`) from the packaged gems. [[#1719](https://github.com/sparklemotion/nokogiri/issues/1719)] (Thanks, [@stevecrozz](https://github.com/stevecrozz)!)
-### Features
+### Added
-* `XML::Attr#value=` allows HTML node attribute values to be set to either a blank string or an empty boolean attribute. [#1800]
-* Introduce `XML::Node#wrap` which does what `XML::NodeSet#wrap` has always done, but for a single node. [#1531] (Thanks, @ethirajsrinivasan!)
-* [MRI] Improve installation experience on macOS High Sierra (Darwin). [#1812, #1813] (Thanks, @gpakosz and @nurse!)
-* [MRI] Node#dup supports copying a node directly to a new document. See the method documentation for details.
-* [MRI] DocumentFragment#dup is now more memory-efficient, avoiding making unnecessary copies. [#1063]
-* [JRuby] NodeSet has been rewritten to improve performance! [#1795]
+* `XML::Attr#value=` allows HTML node attribute values to be set to either a blank string or an empty boolean attribute. [[#1800](https://github.com/sparklemotion/nokogiri/issues/1800)]
+* Introduce `XML::Node#wrap` which does what `XML::NodeSet#wrap` has always done, but for a single node. [[#1531](https://github.com/sparklemotion/nokogiri/issues/1531)] (Thanks, [@ethirajsrinivasan](https://github.com/ethirajsrinivasan)!)
+* [MRI] Improve installation experience on macOS High Sierra (Darwin). [[#1812](https://github.com/sparklemotion/nokogiri/issues/1812), [#1813](https://github.com/sparklemotion/nokogiri/issues/1813)] (Thanks, [@gpakosz](https://github.com/gpakosz) and [@nurse](https://github.com/nurse)!)
+* [MRI] `Node#dup` supports copying a node directly to a new document. See the method documentation for details.
+* [MRI] `DocumentFragment#dup` is now more memory-efficient, avoiding making unnecessary copies. [[#1063](https://github.com/sparklemotion/nokogiri/issues/1063)]
+* [JRuby] `NodeSet` has been rewritten to improve performance! [[#1795](https://github.com/sparklemotion/nokogiri/issues/1795)]
-### Bug fixes
+### Fixed
-* `NodeSet#each` now returns `self` instead of zero. [#1822] (Thanks, @olehif!)
-* [MRI] Address a memory leak when using XML::Builder to create nodes with namespaces. [#1810]
-* [MRI] Address a memory leak when unparenting a DTD. [#1784] (Thanks, @stevecheckoway!)
-* [MRI] Use RbConfig::CONFIG instead of ::MAKEFILE_CONFIG to fix installations that use Makefile macros. [#1820] (Thanks, @nobu!)
-* [JRuby] Decrease large memory usage when making nested XPath queries. [#1749]
+* `NodeSet#each` now returns `self` instead of zero. [[#1822](https://github.com/sparklemotion/nokogiri/issues/1822)] (Thanks, [@olehif](https://github.com/olehif)!)
+* [MRI] Address a memory leak when using `XML::Builder` to create nodes with namespaces. [[#1810](https://github.com/sparklemotion/nokogiri/issues/1810)]
+* [MRI] Address a memory leak when unparenting a DTD. [[#1784](https://github.com/sparklemotion/nokogiri/issues/1784)] (Thanks, [@stevecheckoway](https://github.com/stevecheckoway)!)
+* [MRI] Use `RbConfig::CONFIG` instead of `::MAKEFILE_CONFIG` to fix installations that use Makefile macros. [[#1820](https://github.com/sparklemotion/nokogiri/issues/1820)] (Thanks, [@nobu](https://github.com/nobu)!)
+* [JRuby] Decrease large memory usage when making nested XPath queries. [[#1749](https://github.com/sparklemotion/nokogiri/issues/1749)]
* [JRuby] Fix failing tests on JRuby 9.2.x
-* [JRuby] Fix default namespaces in nodes reparented into a different document [#1774]
-* [JRuby] Fix support for Java 9. [#1759] (Thanks, @Taywee!)
+* [JRuby] Fix default namespaces in nodes reparented into a different document [[#1774](https://github.com/sparklemotion/nokogiri/issues/1774)]
+* [JRuby] Fix support for Java 9. [[#1759](https://github.com/sparklemotion/nokogiri/issues/1759)] (Thanks, [@Taywee](https://github.com/Taywee)!)
### Dependencies
@@ -105,27 +888,27 @@ This release ends support for:
## 1.8.5 / 2018-10-04
-### Security Notes
+### Security
[MRI] Pulled in upstream patches from libxml2 that address CVE-2018-14404 and CVE-2018-14567. Full details are available in [#1785](https://github.com/sparklemotion/nokogiri/issues/1785). Note that these patches are not yet (as of 2018-10-04) in an upstream release of libxml2.
-### Bug fixes
+### Fixed
-* [MRI] Fix regression in installation when building against system libraries, where some systems would not be able to find libxml2 or libxslt when present. (Regression introduced in v1.8.3.) [#1722]
-* [JRuby] Fix node reparenting when the destination doc is empty. [#1773]
+* [MRI] Fix regression in installation when building against system libraries, where some systems would not be able to find libxml2 or libxslt when present. (Regression introduced in v1.8.3.) [[#1722](https://github.com/sparklemotion/nokogiri/issues/1722)]
+* [JRuby] Fix node reparenting when the destination doc is empty. [[#1773](https://github.com/sparklemotion/nokogiri/issues/1773)]
## 1.8.4 / 2018-07-03
-### Bug fixes
+### Fixed
-* [MRI] Fix memory leak when creating nodes with namespaces. (Introduced in v1.5.7) [#1771]
+* [MRI] Fix memory leak when creating nodes with namespaces. (Introduced in v1.5.7) [[#1771](https://github.com/sparklemotion/nokogiri/issues/1771)]
## 1.8.3 / 2018-06-16
-### Security Notes
+### Security
[MRI] Behavior in libxml2 has been reverted which caused CVE-2018-8048 (loofah gem), CVE-2018-3740 (sanitize gem), and CVE-2018-3741 (rails-html-sanitizer gem). The commit in question is here:
@@ -142,34 +925,39 @@ If you're offended by what happened here, I'd kindly ask that you comment on the
> https://bugzilla.gnome.org/show_bug.cgi?id=769760
+### More Security
+
+[MRI] Vendored libxml2 upgraded to v2.9.8 which addresses CVE-2016-9318 [[#1582](https://github.com/sparklemotion/nokogiri/issues/1582)].
+
+
### Dependencies
* [MRI] libxml2 is updated from 2.9.7 to 2.9.8
-### Features
+### Added
-* Node#classes, #add_class, #append_class, and #remove_class are added.
-* NodeSet#append_class is added.
-* NodeSet#remove_attribute is a new alias for NodeSet#remove_attr.
-* NodeSet#each now returns an Enumerator when no block is passed (Thanks, @park53kr!)
-* [JRuby] General improvements in JRuby implementation (Thanks, @kares!)
+* `Node#classes`, `#add_class`, `#append_class`, and `#remove_class` are added.
+* `NodeSet#append_class` is added.
+* `NodeSet#remove_attribute` is a new alias for `NodeSet#remove_attr`.
+* `NodeSet#each` now returns an `Enumerator` when no block is passed (Thanks, [@park53kr](https://github.com/park53kr)!)
+* [JRuby] General improvements in JRuby implementation (Thanks, [@kares](https://github.com/kares)!)
-### Bug fixes
+### Fixed
-* CSS attribute selectors now gracefully handle queries using integers. [#711]
-* Handle ASCII-8BIT encoding on fragment input [#553]
-* Handle non-string return values within `Reader` [#898]
-* [JRuby] Allow Node#replace to insert Comment and CDATA nodes. [#1666]
-* [JRuby] Stability and speed improvements to `Node`, `Sax::PushParser`, and the JRuby implementation [#1708, #1710, #1501]
+* CSS attribute selectors now gracefully handle queries using integers. [[#711](https://github.com/sparklemotion/nokogiri/issues/711)]
+* Handle ASCII-8BIT encoding on fragment input [[#553](https://github.com/sparklemotion/nokogiri/issues/553)]
+* Handle non-string return values within `Reader` [[#898](https://github.com/sparklemotion/nokogiri/issues/898)]
+* [JRuby] Allow `Node#replace` to insert Comment and CDATA nodes. [[#1666](https://github.com/sparklemotion/nokogiri/issues/1666)]
+* [JRuby] Stability and speed improvements to `Node`, `Sax::PushParser`, and the JRuby implementation [[#1708](https://github.com/sparklemotion/nokogiri/issues/1708), [#1710](https://github.com/sparklemotion/nokogiri/issues/1710), [#1501](https://github.com/sparklemotion/nokogiri/issues/1501)]
## 1.8.2 / 2018-01-29
-### Security Notes
+### Security
-[MRI] The update of vendored libxml2 from 2.9.5 to 2.9.7 addresses at least one published vulnerability, CVE-2017-15412. [#1714 has complete details]
+[MRI] The update of vendored libxml2 from 2.9.5 to 2.9.7 addresses at least one published vulnerability, CVE-2017-15412. [[#1714](https://github.com/sparklemotion/nokogiri/issues/1714) has complete details]
### Dependencies
@@ -178,17 +966,17 @@ If you're offended by what happened here, I'd kindly ask that you comment on the
* [MRI] libxslt is updated from 1.1.30 to 1.1.32
-### Features
+### Added
-* [MRI] OpenBSD installation should be a bit easier now. [#1685] (Thanks, @jeremyevans!)
+* [MRI] OpenBSD installation should be a bit easier now. [[#1685](https://github.com/sparklemotion/nokogiri/issues/1685)] (Thanks, [@jeremyevans](https://github.com/jeremyevans)!)
* [MRI] Cross-built Windows gems now support Ruby 2.5
-### Bug fixes
+### Fixed
-* Node#serialize once again returns UTF-8-encoded strings. [#1659]
-* [JRuby] made SAX parsing of characters consistent with C implementation [#1676] (Thanks, @andrew-aladev!)
-* [MRI] Predefined entities, when inspected, no longer cause a segfault. [#1238]
+* `Node#serialize` once again returns UTF-8-encoded strings. [[#1659](https://github.com/sparklemotion/nokogiri/issues/1659)]
+* [JRuby] made SAX parsing of characters consistent with C implementation [[#1676](https://github.com/sparklemotion/nokogiri/issues/1676)] (Thanks, [[@andrew](https://github.com/andrew)-aladev](https://github.com/andrew-aladev)!)
+* [MRI] Predefined entities, when inspected, no longer cause a segfault. [[#1238](https://github.com/sparklemotion/nokogiri/issues/1238)]
## 1.8.1 / 2017-09-19
@@ -197,19 +985,19 @@ If you're offended by what happened here, I'd kindly ask that you comment on the
* [MRI] libxml2 is updated from 2.9.4 to 2.9.5.
* [MRI] libxslt is updated from 1.1.29 to 1.1.30.
-* [MRI] optional dependency on the pkg-config gem has had its constraint loosened to `~> 1.1` (from `~> 1.1.7`). [#1660]
+* [MRI] optional dependency on the pkg-config gem has had its constraint loosened to `~> 1.1` (from `~> 1.1.7`). [[#1660](https://github.com/sparklemotion/nokogiri/issues/1660)]
* [MRI] Upgrade mini_portile2 dependency from `~> 2.2.0` to `~> 2.3.0`, which will validate checksums on the vendored libxml2 and libxslt tarballs before using them.
-### Bugs
+### Fixed
-* NodeSet#first with an integer argument longer than the length of the NodeSet now correctly clamps the length of the returned NodeSet to the original length. [#1650] (Thanks, @Derenge!)
-* [MRI] Ensure CData.new raises TypeError if the `content` argument is not implicitly convertible into a string. [#1669]
+* `NodeSet#first` with an integer argument longer than the length of the `NodeSet` now correctly clamps the length of the returned `NodeSet` to the original length. [[#1650](https://github.com/sparklemotion/nokogiri/issues/1650)] (Thanks, [@Derenge](https://github.com/Derenge)!)
+* [MRI] Ensure CData.new raises TypeError if the `content` argument is not implicitly convertible into a string. [[#1669](https://github.com/sparklemotion/nokogiri/issues/1669)]
## 1.8.0 / 2017-06-04
-### Backwards incompatibilities
+### Dependencies
This release ends support for Ruby 2.1 on Windows in the `x86-mingw32` and `x64-mingw32` platform gems (containing pre-compiled DLLs). Official support ended for Ruby 2.1 on 2017-04-01.
@@ -222,86 +1010,81 @@ Please note that this deprecation note only applies to the precompiled Windows g
* [Windows] Upgrade zlib from 1.2.8 to 1.2.11 (unless --use-system-libraries)
* [MRI] Upgrade rake-compiler dependency from 0.9.2 to 1.0.3
* [MRI] Upgrade mini-portile2 dependency from `~> 2.1.0` to `~> 2.2.0`
+* [JRuby] Removed support for `jruby --1.8` code paths. [[#1607](https://github.com/sparklemotion/nokogiri/issues/1607)] (Thanks, [@kares](https://github.com/kares)!)
+* [MRI Windows] Retrieve zlib source from http://zlib.net/fossils to avoid deprecation issues going forward. See [#1632](https://github.com/sparklemotion/nokogiri/issues/1632) for details around this problem.
+### Added
-### Compatibility notes
-
-* [JRuby] Removed support for `jruby --1.8` code paths. [#1607] (Thanks, @kares!)
-* [MRI Windows] Retrieve zlib source from http://zlib.net/fossils to avoid deprecation issues going forward. See #1632 for details around this problem.
-
-
-### Features
-
-* NodeSet#clone is not an alias for NodeSet#dup [#1503] (Thanks, @stephankaag!)
-* Allow Processing Instructions and Comments as children of a document root. [#1033] (Thanks, @windwiny!)
-* [MRI] PushParser#replace_entities and #replace_entities= will control whether entities are replaced or not. [#1017] (Thanks, @spraints!)
-* [MRI] SyntaxError#to_s now includes line number, column number, and log level if made available by the parser. [#1304, #1637] (Thanks, @spk and @ccarruitero!)
+* `NodeSet#clone` is now an alias for `NodeSet#dup` [[#1503](https://github.com/sparklemotion/nokogiri/issues/1503)] (Thanks, [@stephankaag](https://github.com/stephankaag)!)
+* Allow Processing Instructions and Comments as children of a document root. [[#1033](https://github.com/sparklemotion/nokogiri/issues/1033)] (Thanks, [@windwiny](https://github.com/windwiny)!)
+* [MRI] `PushParser#replace_entities` and `#replace_entities=` will control whether entities are replaced or not. [[#1017](https://github.com/sparklemotion/nokogiri/issues/1017)] (Thanks, [@spraints](https://github.com/spraints)!)
+* [MRI] `SyntaxError#to_s` now includes line number, column number, and log level if made available by the parser. [[#1304](https://github.com/sparklemotion/nokogiri/issues/1304), [#1637](https://github.com/sparklemotion/nokogiri/issues/1637)] (Thanks, [@spk](https://github.com/spk) and [@ccarruitero](https://github.com/ccarruitero)!)
* [MRI] Cross-built Windows gems now support Ruby 2.4
-* [MRI] Support for frozen string literals. [#1413]
-* [MRI] Support for installing Nokogiri on a machine in FIPS-enabled mode [#1544]
-* [MRI] Vendored libraries are verified with SHA-256 hashes (formerly some MD5 hashes were used) [#1544]
-* [JRuby] (performance) remove unnecessary synchronization of class-cache [#1563] (Thanks, @kares!)
-* [JRuby] (performance) remove unnecessary cloning of objects in XPath searches [#1563] (Thanks, @kares!)
-* [JRuby] (performance) more performance improvements, particularly in XPath, Reader, XmlNode, and XmlNodeSet [#1597] (Thanks, @kares!)
+* [MRI] Support for frozen string literals. [[#1413](https://github.com/sparklemotion/nokogiri/issues/1413)]
+* [MRI] Support for installing Nokogiri on a machine in FIPS-enabled mode [[#1544](https://github.com/sparklemotion/nokogiri/issues/1544)]
+* [MRI] Vendored libraries are verified with SHA-256 hashes (formerly some MD5 hashes were used) [[#1544](https://github.com/sparklemotion/nokogiri/issues/1544)]
+* [JRuby] (performance) remove unnecessary synchronization of class-cache [[#1563](https://github.com/sparklemotion/nokogiri/issues/1563)] (Thanks, [@kares](https://github.com/kares)!)
+* [JRuby] (performance) remove unnecessary cloning of objects in XPath searches [[#1563](https://github.com/sparklemotion/nokogiri/issues/1563)] (Thanks, [@kares](https://github.com/kares)!)
+* [JRuby] (performance) more performance improvements, particularly in XPath, Reader, XmlNode, and XmlNodeSet [[#1597](https://github.com/sparklemotion/nokogiri/issues/1597)] (Thanks, [@kares](https://github.com/kares)!)
-### Bugs
+### Fixed
-* HTML::SAX::Parser#parse_io now correctly parses HTML and not XML [#1577] (Thanks for the test case, @gregors!)
-* Support installation on systems with a `lib64` site config. [#1562]
-* [MRI] on OpenBSD, do not require gcc if using system libraries [#1515] (Thanks, @jeremyevans!)
-* [MRI] XML::Attr.new checks type of Document arg to prevent segfaults. [#1477]
-* [MRI] Prefer xmlCharStrdup (and friends) to strdup (and friends), which can cause problems on some platforms. [#1517] (Thanks, @jeremy!)
-* [JRuby] correctly append a text node before another text node [#1318] (Thanks, @jkraemer!)
-* [JRuby] custom xpath functions returning an integer now work correctly [#1595] (Thanks, @kares!)
-* [JRuby] serializing (`#to_html`, `#to_s`, et al) a document with explicit encoding now works correctly. [#1281, #1440] (Thanks, @kares!)
-* [JRuby] XML::Reader now returns parse errors [#1586] (Thanks, @kares!)
-* [JRuby] Empty NodeSets are now decorated properly. [#1319] (Thanks, @kares!)
-* [JRuby] Merged nodes no longer results in Java exceptions during XPath queries. [#1320] (Thanks, @kares!)
+* `HTML::SAX::Parser#parse_io` now correctly parses HTML and not XML [[#1577](https://github.com/sparklemotion/nokogiri/issues/1577)] (Thanks for the test case, [@gregors](https://github.com/gregors)!)
+* Support installation on systems with a `lib64` site config. [[#1562](https://github.com/sparklemotion/nokogiri/issues/1562)]
+* [MRI] on OpenBSD, do not require gcc if using system libraries [[#1515](https://github.com/sparklemotion/nokogiri/issues/1515)] (Thanks, [@jeremyevans](https://github.com/jeremyevans)!)
+* [MRI] `XML::Attr.new` checks type of Document arg to prevent segfaults. [[#1477](https://github.com/sparklemotion/nokogiri/issues/1477)]
+* [MRI] Prefer xmlCharStrdup (and friends) to strdup (and friends), which can cause problems on some platforms. [[#1517](https://github.com/sparklemotion/nokogiri/issues/1517)] (Thanks, [@jeremy](https://github.com/jeremy)!)
+* [JRuby] correctly append a text node before another text node [[#1318](https://github.com/sparklemotion/nokogiri/issues/1318)] (Thanks, [@jkraemer](https://github.com/jkraemer)!)
+* [JRuby] custom xpath functions returning an integer now work correctly [[#1595](https://github.com/sparklemotion/nokogiri/issues/1595)] (Thanks, [@kares](https://github.com/kares)!)
+* [JRuby] serializing (`#to_html`, `#to_s`, et al) a document with explicit encoding now works correctly. [[#1281](https://github.com/sparklemotion/nokogiri/issues/1281), [#1440](https://github.com/sparklemotion/nokogiri/issues/1440)] (Thanks, [@kares](https://github.com/kares)!)
+* [JRuby] `XML::Reader` now returns parse errors [[#1586](https://github.com/sparklemotion/nokogiri/issues/1586)] (Thanks, [@kares](https://github.com/kares)!)
+* [JRuby] Empty `NodeSet`s are now decorated properly. [[#1319](https://github.com/sparklemotion/nokogiri/issues/1319)] (Thanks, [@kares](https://github.com/kares)!)
+* [JRuby] Merged nodes no longer results in Java exceptions during XPath queries. [[#1320](https://github.com/sparklemotion/nokogiri/issues/1320)] (Thanks, [@kares](https://github.com/kares)!)
## 1.7.2 / 2017-05-09
-### Security Notes
+### Security
[MRI] Upstream libxslt patches are applied to the vendored libxslt 1.1.29 which address CVE-2017-5029 and CVE-2016-4738.
For more information:
-* https://github.com/sparklemotion/nokogiri/issues/1634
+* [#1634](https://github.com/sparklemotion/nokogiri/issues/1634)
* http://people.canonical.com/~ubuntu-security/cve/2017/CVE-2017-5029.html
* http://people.canonical.com/~ubuntu-security/cve/2016/CVE-2016-4738.html
## 1.7.1 / 2017-03-19
-### Security Notes
+### Security
[MRI] Upstream libxml2 patches are applied to the vendored libxml 2.9.4 which address CVE-2016-4658 and CVE-2016-5131.
For more information:
-* https://github.com/sparklemotion/nokogiri/issues/1615
+* [#1615](https://github.com/sparklemotion/nokogiri/issues/1615)
* http://people.canonical.com/~ubuntu-security/cve/2016/CVE-2016-4658.html
* http://people.canonical.com/~ubuntu-security/cve/2016/CVE-2016-5131.html
## 1.7.0.1 / 2017-01-04
-### Bugs
+### Fixed
-* Fix OpenBSD support. (#1569) (related to #1543)
+* Fix OpenBSD support. ([#1569](https://github.com/sparklemotion/nokogiri/issues/1569)) (related to [#1543](https://github.com/sparklemotion/nokogiri/issues/1543))
## 1.7.0 / 2016-12-26
-### Features
+### Added
-* Remove deprecation warnings in Ruby 2.4.0 (#1545) (Thanks, @matthewd!)
-* Support egcc compiler on OpenBSD (#1543) (Thanks, @frenkel and @knu!)
+* Remove deprecation warnings in Ruby 2.4.0 ([#1545](https://github.com/sparklemotion/nokogiri/issues/1545)) (Thanks, [@matthewd](https://github.com/matthewd)!)
+* Support egcc compiler on OpenBSD ([#1543](https://github.com/sparklemotion/nokogiri/issues/1543)) (Thanks, [@frenkel](https://github.com/frenkel) and [@knu](https://github.com/knu)!)
-### Backwards incompatibilities.
+### Dependencies
This release ends support for:
@@ -313,11 +1096,11 @@ This release ends support for:
## 1.6.8.1 / 2016-10-03
-### Dependency License Notes
+### Dependencies
Removes required dependency on the `pkg-config` gem. This dependency
was introduced in v1.6.8 and, because it's distributed under LGPL, was
-objectionable to many Nokogiri users (#1488, #1496).
+objectionable to many Nokogiri users ([#1488](https://github.com/sparklemotion/nokogiri/issues/1488), [#1496](https://github.com/sparklemotion/nokogiri/issues/1496)).
This version makes `pkg-config` an optional dependency. If it's
installed, it's used; but otherwise Nokogiri will attempt to work
@@ -326,7 +1109,7 @@ around its absence.
## 1.6.8 / 2016-06-06
-### Security Notes
+### Security
[MRI] Bundled libxml2 is upgraded to 2.9.4, which fixes many security issues. Many of these had previously been patched in the vendored libxml 2.9.2 in the 1.6.7.x branch, but some are newer.
@@ -347,46 +1130,46 @@ See this libxslt email post for more:
* https://mail.gnome.org/archives/xslt/2016-May/msg00004.html
-### Features
+### Added
Several changes were made to improve performance:
-* [MRI] Simplify NodeSet#to_a with a minor speed-up. (#1397)
-* XML::Node#ancestors optimization. (#1297) (Thanks, Bruno Sutic!)
-* Use Symbol#to_proc where we weren't previously. (#1296) (Thanks, Bruno Sutic!)
-* XML::DTD#each uses implicit block calls. (Thanks, @glaucocustodio!)
-* Fall back to the `pkg-config` gem if we're having trouble finding the system libxml2. This should help many FreeBSD users. (#1417)
-* Set document encoding appropriately even on blank document. (#1043) (Thanks, @batter!)
-
-
-### Bug Fixes
-
-* [JRuby] fix slow add_child (#692)
-* [JRuby] fix load errors when deploying to JRuby/Torquebox (#1114) (Thanks, @atambo and @jvshahid!)
-* [JRuby] fix NPE when inspecting nodes returned by NodeSet#drop (#1042) (Thanks, @mkristian!)
-* [JRuby] fix nil attriubte node's namespace in reader (#1327) (Thanks, @codekitchen!)
-* [JRuby] fix Nokogiri munging unicode characters that require more than 2 bytes (#1113) (Thanks, @mkristian!)
-* [JRuby] allow unlinking an unparented node (#1112, #1152) (Thanks, @esse!)
-* [JRuby] allow Fragment parsing on a frozen string (#444, #1077)
-* [JRuby] HTML `style` tags are no longer encoded (#1316) (Thanks, @tbeauvais!)
-* [MRI] fix assertion failure while accessing attribute node's namespace in reader (#843) (Thanks, @2potatocakes!)
-* [MRI] fix issue with GCing namespace nodes returned in an xpath query. (#1155)
-* [MRI] Ensure C strings are null-terminated. (#1381)
-* [MRI] Ensure Rubygems is loaded before using mini_portile2 at installation. (#1393, #1411) (Thanks, @JonRowe!)
-* [MRI] Handling another edge case where the `libxml-ruby` gem's global callbacks were smashing the heap. (#1426). (Thanks to @bbergstrom for providing an isolated test case!)
-* [MRI] Ensure encodings are passed to Sax::Parser xmldecl callback. (#844)
-* [MRI] Ensure default ns prefix is applied correctly when reparenting nodes to another document. (#391) (Thanks, @ylecuyer!)
-* [MRI] Ensure Reader handles non-existent attributes as expected. (#1254) (Thanks, @ccutrer!)
-* [MRI] Cleanup around namespace handling when reparenting nodes. (#1332, #1333, #1444) (Thanks, @cuttrer and @bradleybeddoes!)
-* unescape special characters in CSS queries (#1303) (Thanks, @twalpole!)
-* consistently handle empty documents (#1349)
-* Update to mini_portile2 2.1.0 to address whitespace-handling during patching. (#1402)
+* [MRI] Simplify `NodeSet#to_a` with a minor speed-up. ([#1397](https://github.com/sparklemotion/nokogiri/issues/1397))
+* `XML::Node#ancestors` optimization. ([#1297](https://github.com/sparklemotion/nokogiri/issues/1297)) (Thanks, Bruno Sutic!)
+* Use `Symbol#to_proc` where we weren't previously. ([#1296](https://github.com/sparklemotion/nokogiri/issues/1296)) (Thanks, Bruno Sutic!)
+* `XML::DTD#each` uses implicit block calls. (Thanks, [@glaucocustodio](https://github.com/glaucocustodio)!)
+* Fall back to the `pkg-config` gem if we're having trouble finding the system libxml2. This should help many FreeBSD users. ([#1417](https://github.com/sparklemotion/nokogiri/issues/1417))
+* Set document encoding appropriately even on blank document. ([#1043](https://github.com/sparklemotion/nokogiri/issues/1043)) (Thanks, [@batter](https://github.com/batter)!)
+
+
+### Fixed
+
+* [JRuby] fix slow add_child ([#692](https://github.com/sparklemotion/nokogiri/issues/692))
+* [JRuby] fix load errors when deploying to JRuby/Torquebox ([#1114](https://github.com/sparklemotion/nokogiri/issues/1114)) (Thanks, [@atambo](https://github.com/atambo) and [@jvshahid](https://github.com/jvshahid)!)
+* [JRuby] fix NPE when inspecting nodes returned by `NodeSet#drop` ([#1042](https://github.com/sparklemotion/nokogiri/issues/1042)) (Thanks, [@mkristian](https://github.com/mkristian)!)
+* [JRuby] fix nil attriubte node's namespace in reader ([#1327](https://github.com/sparklemotion/nokogiri/issues/1327)) (Thanks, [@codekitchen](https://github.com/codekitchen)!)
+* [JRuby] fix Nokogiri munging unicode characters that require more than 2 bytes ([#1113](https://github.com/sparklemotion/nokogiri/issues/1113)) (Thanks, [@mkristian](https://github.com/mkristian)!)
+* [JRuby] allow unlinking an unparented node ([#1112](https://github.com/sparklemotion/nokogiri/issues/1112), [#1152](https://github.com/sparklemotion/nokogiri/issues/1152)) (Thanks, [@esse](https://github.com/esse)!)
+* [JRuby] allow Fragment parsing on a frozen string ([#444](https://github.com/sparklemotion/nokogiri/issues/444), [#1077](https://github.com/sparklemotion/nokogiri/issues/1077))
+* [JRuby] HTML `style` tags are no longer encoded ([#1316](https://github.com/sparklemotion/nokogiri/issues/1316)) (Thanks, [@tbeauvais](https://github.com/tbeauvais)!)
+* [MRI] fix assertion failure while accessing attribute node's namespace in reader ([#843](https://github.com/sparklemotion/nokogiri/issues/843)) (Thanks, [@2potatocakes](https://github.com/2potatocakes)!)
+* [MRI] fix issue with GCing namespace nodes returned in an xpath query. ([#1155](https://github.com/sparklemotion/nokogiri/issues/1155))
+* [MRI] Ensure C strings are null-terminated. ([#1381](https://github.com/sparklemotion/nokogiri/issues/1381))
+* [MRI] Ensure Rubygems is loaded before using mini_portile2 at installation. ([#1393](https://github.com/sparklemotion/nokogiri/issues/1393), [#1411](https://github.com/sparklemotion/nokogiri/issues/1411)) (Thanks, [@JonRowe](https://github.com/JonRowe)!)
+* [MRI] Handling another edge case where the `libxml-ruby` gem's global callbacks were smashing the heap. ([#1426](https://github.com/sparklemotion/nokogiri/issues/1426)). (Thanks to [@bbergstrom](https://github.com/bbergstrom) for providing an isolated test case!)
+* [MRI] Ensure encodings are passed to `Sax::Parser` xmldecl callback. ([#844](https://github.com/sparklemotion/nokogiri/issues/844))
+* [MRI] Ensure default ns prefix is applied correctly when reparenting nodes to another document. ([#391](https://github.com/sparklemotion/nokogiri/issues/391)) (Thanks, [@ylecuyer](https://github.com/ylecuyer)!)
+* [MRI] Ensure Reader handles non-existent attributes as expected. ([#1254](https://github.com/sparklemotion/nokogiri/issues/1254)) (Thanks, [@ccutrer](https://github.com/ccutrer)!)
+* [MRI] Cleanup around namespace handling when reparenting nodes. ([#1332](https://github.com/sparklemotion/nokogiri/issues/1332), [#1333](https://github.com/sparklemotion/nokogiri/issues/1333), [#1444](https://github.com/sparklemotion/nokogiri/issues/1444)) (Thanks, [@cuttrer](https://github.com/cuttrer) and [@bradleybeddoes](https://github.com/bradleybeddoes)!)
+* unescape special characters in CSS queries ([#1303](https://github.com/sparklemotion/nokogiri/issues/1303)) (Thanks, [@twalpole](https://github.com/twalpole)!)
+* consistently handle empty documents ([#1349](https://github.com/sparklemotion/nokogiri/issues/1349))
+* Update to mini_portile2 2.1.0 to address whitespace-handling during patching. ([#1402](https://github.com/sparklemotion/nokogiri/issues/1402))
* Fix encoding of xml node namespaces.
-* Work around issue installing Nokogiri on overlayfs (commonly used in Docker containers). (#1370, #1405)
+* Work around issue installing Nokogiri on overlayfs (commonly used in Docker containers). ([#1370](https://github.com/sparklemotion/nokogiri/issues/1370), [#1405](https://github.com/sparklemotion/nokogiri/issues/1405))
-### Other Notes
+### Notes
* Removed legacy code remaining from Ruby 1.8.x support.
* Removed legacy code remaining from REE support.
@@ -398,7 +1181,7 @@ Several changes were made to improve performance:
This version pulls in several upstream patches to the vendored libxml2 and libxslt to address:
- CVE-2015-7499
+* CVE-2015-7499
Ubuntu classifies this as "Priority: Low", RedHat classifies this as "Impact: Moderate", and NIST classifies this as "Severity: 5.0 (MEDIUM)".
@@ -409,54 +1192,56 @@ MITRE record is https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-7499
This version pulls in several upstream patches to the vendored libxml2 and libxslt to address:
- CVE-2015-5312
- CVE-2015-7497
- CVE-2015-7498
- CVE-2015-7499
- CVE-2015-7500
- CVE-2015-8241
- CVE-2015-8242
- CVE-2015-8317
+* CVE-2015-5312
+* CVE-2015-7497
+* CVE-2015-7498
+* CVE-2015-7499
+* CVE-2015-7500
+* CVE-2015-8241
+* CVE-2015-8242
+* CVE-2015-8317
See also http://www.ubuntu.com/usn/usn-2834-1/
## 1.6.7 / 2015-11-29
-### Notes
+### Added
This version supports native builds on Windows using the RubyInstaller
DevKit. It also supports Ruby 2.2.x on Windows, as well as making
several other improvements to the installation process on various
platforms.
+### Security
+
This version also includes the security patches already applied in
v1.6.6.3 and v1.6.6.4 to the vendored libxml2 and libxslt source.
-See #1374 and #1376 for details.
+See [#1374](https://github.com/sparklemotion/nokogiri/issues/1374) and [#1376](https://github.com/sparklemotion/nokogiri/issues/1376) for details.
-### Features
+### Added
-* Cross-built gems now have a proper ruby version requirement. (#1266)
+* Cross-built gems now have a proper ruby version requirement. ([#1266](https://github.com/sparklemotion/nokogiri/issues/1266))
* Ruby 2.2.x is supported on Windows.
* Native build is supported on Windows.
-* [MRI] libxml2 and libxslt `config.guess` files brought up to date. (#1326) (Thanks, @hernan-erasmo!)
-* [JRuby] fix error in validating files with jruby (#1355, #1361) (Thanks, @twalpole!)
-* [MRI, OSX] Patch to handle nonstandard location of `iconv.h`. (#1206, #1210, #1218, #1345) (Thanks, @neonichu!)
+* [MRI] libxml2 and libxslt `config.guess` files brought up to date. ([#1326](https://github.com/sparklemotion/nokogiri/issues/1326)) (Thanks, [[@hernan](https://github.com/hernan)-erasmo](https://github.com/hernan-erasmo)!)
+* [JRuby] fix error in validating files with jruby ([#1355](https://github.com/sparklemotion/nokogiri/issues/1355), [#1361](https://github.com/sparklemotion/nokogiri/issues/1361)) (Thanks, [@twalpole](https://github.com/twalpole)!)
+* [MRI, OSX] Patch to handle nonstandard location of `iconv.h`. ([#1206](https://github.com/sparklemotion/nokogiri/issues/1206), [#1210](https://github.com/sparklemotion/nokogiri/issues/1210), [#1218](https://github.com/sparklemotion/nokogiri/issues/1218), [#1345](https://github.com/sparklemotion/nokogiri/issues/1345)) (Thanks, [@neonichu](https://github.com/neonichu)!)
-### Bug Fixes
+### Fixed
-* [JRuby] reset the namespace cache when replacing the document's innerHtml (#1265) (Thanks, @mkristian!)
-* [JRuby] Document#parse should support IO objects that respond to #read. (#1124) (Thanks, Jake Byman!)
-* [MRI] Duplicate-id errors when setting the `id` attribute on HTML documents are now silenced. (#1262)
-* [JRuby] SAX parser cuts texts in pieces when square brackets exist. (#1261)
-* [JRuby] Namespaced attributes aren't removed by remove_attribute. (#1299)
+* [JRuby] reset the namespace cache when replacing the document's innerHtml ([#1265](https://github.com/sparklemotion/nokogiri/issues/1265)) (Thanks, [@mkristian](https://github.com/mkristian)!)
+* [JRuby] `Document#parse` should support IO objects that respond to `#read`. ([#1124](https://github.com/sparklemotion/nokogiri/issues/1124)) (Thanks, Jake Byman!)
+* [MRI] Duplicate-id errors when setting the `id` attribute on HTML documents are now silenced. ([#1262](https://github.com/sparklemotion/nokogiri/issues/1262))
+* [JRuby] SAX parser cuts texts in pieces when square brackets exist. ([#1261](https://github.com/sparklemotion/nokogiri/issues/1261))
+* [JRuby] Namespaced attributes aren't removed by remove_attribute. ([#1299](https://github.com/sparklemotion/nokogiri/issues/1299))
## 1.6.6.4 / 2015-11-19
This version pulls in an upstream patch to the vendored libxml2 to address:
-* unclosed comment uninitialized access issue (#1376)
+* unclosed comment uninitialized access issue ([#1376](https://github.com/sparklemotion/nokogiri/issues/1376))
This issue was assigned CVE-2015-8710 after the fact. See http://seclists.org/oss-sec/2015/q4/616 for details.
@@ -473,14 +1258,14 @@ This version pulls in several upstream patches to the vendored libxml2 and libxs
* CVE-2015-8035
* CVE-2015-7995
-See #1374 for details.
+See [#1374](https://github.com/sparklemotion/nokogiri/issues/1374) for details.
## 1.6.6.2 / 2015-01-23
-### Bug fixes
+### Fixed
-* Fixed installation issue affecting compiler arguments. (#1230)
+* Fixed installation issue affecting compiler arguments. ([#1230](https://github.com/sparklemotion/nokogiri/issues/1230))
## 1.6.6.1 / 2015-01-22
@@ -488,102 +1273,102 @@ See #1374 for details.
Note that 1.6.6.0 was not released.
-### Features
+### Added
-* Unified Node and NodeSet implementations of #search, #xpath and #css.
-* Added Node#lang and Node#lang=.
-* bin/nokogiri passes the URI to parse() if an HTTP URL is given.
-* bin/nokogiri now loads ~/.nokogirirc so user can define helper methods, etc.
-* bin/nokogiri can be configured to use Pry instead of IRB by adding a couple of lines to ~/.nokogirirc. (#1198)
-* bin/nokogiri can better handle urls from STDIN (aiding use of xargs). (#1065)
+* Unified `Node` and `NodeSet` implementations of `#search`, `#xpath` and `#css`.
+* Added `Node#lang` and `Node#lang=`.
+* `bin/nokogiri` passes the URI to `parse()` if an HTTP URL is given.
+* `bin/nokogiri` now loads `~/.nokogirirc` so user can define helper methods, etc.
+* `bin/nokogiri` can be configured to use Pry instead of IRB by adding a couple of lines to ~/.nokogirirc. ([#1198](https://github.com/sparklemotion/nokogiri/issues/1198))
+* `bin/nokogiri` can better handle urls from STDIN (aiding use of xargs). ([#1065](https://github.com/sparklemotion/nokogiri/issues/1065))
* JRuby 9K support.
-### Bug fixes
+### Fixed
-* DocumentFragment#search now matches against root nodes. (#1205)
-* (MRI) More fixes related to handling libxml2 parse errors during DocumentFragment#dup. (#1196)
-* (JRuby) Builder now handles namespace hrefs properly when there is a default ns. (#1039)
-* (JRuby) Clear the XPath cache on attr removal. (#1109)
-* `XML::Comment.new` argument types are now consistent and safe (and documented) across MRI and JRuby. (#1224)
-* (MRI) Restoring support for Ruby 1.9.2 that was broken in v1.6.4.1 and v1.6.5. (#1207)
-* Check if `zlib` is available before building `libxml2`. (#1188)
-* (JRuby) HtmlSaxPushParser now exists. (#1147) (Thanks, Piotr Szmielew!)
+* `DocumentFragment#search` now matches against root nodes. ([#1205](https://github.com/sparklemotion/nokogiri/issues/1205))
+* (MRI) More fixes related to handling libxml2 parse errors during `DocumentFragment#dup`. ([#1196](https://github.com/sparklemotion/nokogiri/issues/1196))
+* (JRuby) Builder now handles namespace hrefs properly when there is a default ns. ([#1039](https://github.com/sparklemotion/nokogiri/issues/1039))
+* (JRuby) Clear the XPath cache on attr removal. ([#1109](https://github.com/sparklemotion/nokogiri/issues/1109))
+* `XML::Comment.new` argument types are now consistent and safe (and documented) across MRI and JRuby. ([#1224](https://github.com/sparklemotion/nokogiri/issues/1224))
+* (MRI) Restoring support for Ruby 1.9.2 that was broken in v1.6.4.1 and v1.6.5. ([#1207](https://github.com/sparklemotion/nokogiri/issues/1207))
+* Check if `zlib` is available before building `libxml2`. ([#1188](https://github.com/sparklemotion/nokogiri/issues/1188))
+* (JRuby) HtmlSaxPushParser now exists. ([#1147](https://github.com/sparklemotion/nokogiri/issues/1147)) (Thanks, Piotr Szmielew!)
## 1.6.5 / 2014-11-26
-### Features
+### Added
-* Implement Slop#respond_to_missing?. (#1176)
+* Implement `Slop#respond_to_missing?`. ([#1176](https://github.com/sparklemotion/nokogiri/issues/1176))
* Optimized the XPath query generated by an `an+b` CSS query.
-### Bug fixes
+### Fixed
-* Capture non-parse errors from Document#dup in Document#errors. (#1196)
-* (JRuby) Document#canonicalize parameters are now consistent with MRI. (#1189)
+* Capture non-parse errors from `Document#dup` in `Document#errors`. ([#1196](https://github.com/sparklemotion/nokogiri/issues/1196))
+* (JRuby) `Document#canonicalize` parameters are now consistent with MRI. ([#1189](https://github.com/sparklemotion/nokogiri/issues/1189))
## 1.6.4.1 / 2014-11-05
-### Bug fixes
+### Fixed
-* (MRI) Fix a bug where CFLAGS passed in are dropped. (#1188)
-* Fix a bug where CSS selector :nth(n) did not work. (#1187)
+* (MRI) Fix a bug where CFLAGS passed in are dropped. ([#1188](https://github.com/sparklemotion/nokogiri/issues/1188))
+* Fix a bug where CSS selector :nth(n) did not work. ([#1187](https://github.com/sparklemotion/nokogiri/issues/1187))
## 1.6.4 / 2014-11-04
-### Features
+### Added
* (MRI) Bundled Libxml2 is upgraded to 2.9.2.
* (MRI) `nokogiri --version` will include a list of applied patches.
* (MRI) Nokogiri no longer prints messages directly to TTY while building the extension.
-* (MRI) Detect and help user fix a missing /usr/include/iconv.h on OS X. (#1111)
+* (MRI) Detect and help user fix a missing /usr/include/iconv.h on OS X. ([#1111](https://github.com/sparklemotion/nokogiri/issues/1111))
* (MRI) Improve the iconv detection for building libxml2.
-### Bug fixes
+### Fixed
-* (MRI) Fix DocumentFragment#element_children (#1138).
-* Fix a bug with CSS attribute selector without any prefix where "foo [bar]" was treated as "foo[bar]". (#1174)
+* (MRI) Fix `DocumentFragment#element_children` ([#1138](https://github.com/sparklemotion/nokogiri/issues/1138)).
+* Fix a bug with CSS attribute selector without any prefix where "foo [bar]" was treated as "foo[bar]". ([#1174](https://github.com/sparklemotion/nokogiri/issues/1174))
## 1.6.3.1 / 2014-07-21
-### Bug fixes
+### Fixed
-* Addressing an Apple Macintosh installation problem for GCC users. #1130 (Thanks, @zenspider!)
+* Addressing an Apple Macintosh installation problem for GCC users. [#1130](https://github.com/sparklemotion/nokogiri/issues/1130) (Thanks, [@zenspider](https://github.com/zenspider)!)
## 1.6.3 / 2014-07-20
-### Features
+### Added
-* Added Node#document? and Node#processing_instruction?
+* Added `Node#document?` and `Node#processing_instruction?`
-### Bug fixes
+### Fixed
-* [JRuby] Fix Ruby memory exhaustion vulnerability. #1087 (Thanks, @ocher)
-* [MRI] Fix segfault during GC when using `libxml-ruby` and `nokogiri` together in multi-threaded environment. #895 (Thanks, @ender672!)
-* Building on OSX 10.9 stock ruby 2.0.0 now works. #1101 (Thanks, @zenspider!)
-* Node#parse now works again for HTML document nodes (broken in 1.6.2+).
-* Processing instructions can now be added via Node#add_next_sibling.
+* [JRuby] Fix Ruby memory exhaustion vulnerability. [#1087](https://github.com/sparklemotion/nokogiri/issues/1087) (Thanks, [@ocher](https://github.com/ocher))
+* [MRI] Fix segfault during GC when using `libxml-ruby` and `nokogiri` together in multi-threaded environment. [#895](https://github.com/sparklemotion/nokogiri/issues/895) (Thanks, [@ender672](https://github.com/ender672)!)
+* Building on OSX 10.9 stock ruby 2.0.0 now works. [#1101](https://github.com/sparklemotion/nokogiri/issues/1101) (Thanks, [@zenspider](https://github.com/zenspider)!)
+* `Node#parse` now works again for HTML document nodes (broken in 1.6.2+).
+* Processing instructions can now be added via `Node#add_next_sibling`.
## 1.6.2.1 / 2014-05-13
-### Bug fixes
+### Fixed
-* Fix statically-linked libxml2 installation when using universal builds of Ruby. #1104
-* Patching `mini_portile` to address the git dependency detailed in #1102.
-* Library load fix to address segfault reported on some systems. #1097
+* Fix statically-linked libxml2 installation when using universal builds of Ruby. [#1104](https://github.com/sparklemotion/nokogiri/issues/1104)
+* Patching `mini_portile` to address the git dependency detailed in [#1102](https://github.com/sparklemotion/nokogiri/issues/1102).
+* Library load fix to address segfault reported on some systems. [#1097](https://github.com/sparklemotion/nokogiri/issues/1097)
## 1.6.2 / 2014-05-12
-### Security Note
+### Security
A set of security and bugfix patches have been backported from the libxml2 and libxslt repositories onto the version of 2.8.0 packaged with Nokogiri, including these notable security fixes:
@@ -593,55 +1378,55 @@ A set of security and bugfix patches have been backported from the libxml2 and l
It is recommended that you upgrade from 1.6.x to this version as soon as possible.
-### Compatibility Note
+### Dependencies
Now requires libxml >= 2.6.21 (was previously >= 2.6.17).
-### Features
+### Added
-* Add cross building of fat binary gems for 64-Bit Windows (x64-mingw32) and add support for native builds on Windows. #864, #989, #1072
+* Add cross building of fat binary gems for 64-Bit Windows (x64-mingw32) and add support for native builds on Windows. [#864](https://github.com/sparklemotion/nokogiri/issues/864), [#989](https://github.com/sparklemotion/nokogiri/issues/989), [#1072](https://github.com/sparklemotion/nokogiri/issues/1072)
* (MRI) Alias CP932 to Windows-31J if iconv does not support Windows-31J.
-* (MRI) Nokogiri now links packaged libraries statically. To disable static linking, pass --disable-static to extconf.rb. #923
-* (MRI) Fix a library path (LIBPATH) precedence problem caused by CRuby bug #9760.
-* (MRI) Nokogiri automatically deletes directories of packaged libraries only used during build. To keep them for debugging purposes, pass --disable-clean to extconf.rb. #952
+* (MRI) Nokogiri now links packaged libraries statically. To disable static linking, pass --disable-static to `extconf.rb`. [#923](https://github.com/sparklemotion/nokogiri/issues/923)
+* (MRI) Fix a library path (LIBPATH) precedence problem caused by CRuby bug [#9760](https://github.com/sparklemotion/nokogiri/issues/9760).
+* (MRI) Nokogiri automatically deletes directories of packaged libraries only used during build. To keep them for debugging purposes, pass --disable-clean to `extconf.rb`. [#952](https://github.com/sparklemotion/nokogiri/issues/952)
* (MRI) Nokogiri now builds libxml2 properly with iconv support on platforms where libiconv is installed outside the system default directories, such as FreeBSD.
-* Add support for an-b in nth selectors. #886 (Thanks, Magnus Bergmark!)
-* Add support for bare and multiple :not() functions in selectors. #887 (Thanks, Magnus Bergmark!)
-* (MRI) Add an extconf.rb option --use-system-libraries, alternative to setting the environment variable NOKOGIRI_USE_SYSTEM_LIBRARIES.
+* Add support for an-b in nth selectors. [#886](https://github.com/sparklemotion/nokogiri/issues/886) (Thanks, Magnus Bergmark!)
+* Add support for bare and multiple `:not()` functions in selectors. [#887](https://github.com/sparklemotion/nokogiri/issues/887) (Thanks, Magnus Bergmark!)
+* (MRI) Add an `extconf.rb` option --use-system-libraries, alternative to setting the environment variable NOKOGIRI_USE_SYSTEM_LIBRARIES.
* (MRI) Update packaged libraries: libxslt to 1.1.28, zlib to 1.2.8, and libiconv to 1.14, respectively.
-* Nokogiri::HTML::Document#title= and #meta_encoding= now always add an element if not present, trying hard to find the best place to put it.
-* Nokogiri::XML::DTD#html_dtd? and #html5_dtd? are added.
-* Nokogiri::XML::Node#prepend_child is added. #664
-* Nokogiri::XML::SAX::ParserContext#recovery is added. #453
-* Fix documentation for XML::Node#namespace. #803 #802 (Thanks, Hoylen Sue)
-* Allow Nokogiri::XML::Node#parse from unparented non-element nodes. #407
-
-### Bugfixes
-
-* Ensure :only-child pseudo class works within :not pseudo class. #858 (Thanks, Yamagishi Kazutoshi!)
-* Don't call pkg_config when using bundled libraries in extconf.rb #931 (Thanks, Shota Fukumori!)
-* Nokogiri.parse() does not mistake a non-HTML document like a RSS document as HTML document. #932 (Thanks, Yamagishi Kazutoshi!)
-* (MRI) Perform a node type check before adding a child node to another. Previously adding a text node to another as a child could cause a SEGV. #1092
-* (JRuby) XSD validation crashes in Java version. #373
-* (JRuby) Document already has a root node error while using Builder. #646
-* (JRuby) c14n tests are all passing on JRuby. #226
-* Parsing empty documents raise SyntaxError in strict mode. #1005
-* (JRuby) Make xpath faster by caching the xpath context. #741
-* (JRuby) XML SAX push parser leaks memory on JRuby, but not on MRI. #998
-* (JRuby) Inconsistent behavior aliasing the default namespace. #940
-* (JRuby) Inconsistent behavior between parsing and adding namespaces. #943
-* (JRuby) Xpath returns inconsistent result set on cloned document with namespaces and attributes. #1034
-* (JRuby) Java-Implementation forgets element namespaces #902
-* (JRuby) JRuby-Nokogiri does not recognise attributes inside namespaces #1081
-* (JRuby) JRuby-Nokogiri has different comment node name #1080
-* (JRuby) JAXPExtensionsProvider / Java 7 / Secure Processing #1070
+* `Nokogiri::HTML::Document#title=` and `#meta_encoding`= now always add an element if not present, trying hard to find the best place to put it.
+* `Nokogiri::XML::DTD#html_dtd?` and `#html5_dtd?` are added.
+* `Nokogiri::XML::Node#prepend_child` is added. [#664](https://github.com/sparklemotion/nokogiri/issues/664)
+* `Nokogiri::XML::SAX::ParserContext#recovery` is added. [#453](https://github.com/sparklemotion/nokogiri/issues/453)
+* Fix documentation for `XML::Node#namespace`. [#803](https://github.com/sparklemotion/nokogiri/issues/803) [#802](https://github.com/sparklemotion/nokogiri/issues/802) (Thanks, Hoylen Sue)
+* Allow `Nokogiri::XML::Node#parse` from unparented non-element nodes. [#407](https://github.com/sparklemotion/nokogiri/issues/407)
+
+### Fixed
+
+* Ensure :only-child pseudo class works within :not pseudo class. [#858](https://github.com/sparklemotion/nokogiri/issues/858) (Thanks, Yamagishi Kazutoshi!)
+* Don't call pkg_config when using bundled libraries in `extconf.rb` [#931](https://github.com/sparklemotion/nokogiri/issues/931) (Thanks, Shota Fukumori!)
+* `Nokogiri.parse()` does not mistake a non-HTML document like a RSS document as HTML document. [#932](https://github.com/sparklemotion/nokogiri/issues/932) (Thanks, Yamagishi Kazutoshi!)
+* (MRI) Perform a node type check before adding a child node to another. Previously adding a text node to another as a child could cause a SEGV. [#1092](https://github.com/sparklemotion/nokogiri/issues/1092)
+* (JRuby) XSD validation crashes in Java version. [#373](https://github.com/sparklemotion/nokogiri/issues/373)
+* (JRuby) Document already has a root node error while using Builder. [#646](https://github.com/sparklemotion/nokogiri/issues/646)
+* (JRuby) c14n tests are all passing on JRuby. [#226](https://github.com/sparklemotion/nokogiri/issues/226)
+* Parsing empty documents raise `SyntaxError` in strict mode. [#1005](https://github.com/sparklemotion/nokogiri/issues/1005)
+* (JRuby) Make xpath faster by caching the xpath context. [#741](https://github.com/sparklemotion/nokogiri/issues/741)
+* (JRuby) XML SAX push parser leaks memory on JRuby, but not on MRI. [#998](https://github.com/sparklemotion/nokogiri/issues/998)
+* (JRuby) Inconsistent behavior aliasing the default namespace. [#940](https://github.com/sparklemotion/nokogiri/issues/940)
+* (JRuby) Inconsistent behavior between parsing and adding namespaces. [#943](https://github.com/sparklemotion/nokogiri/issues/943)
+* (JRuby) Xpath returns inconsistent result set on cloned document with namespaces and attributes. [#1034](https://github.com/sparklemotion/nokogiri/issues/1034)
+* (JRuby) Java-Implementation forgets element namespaces [#902](https://github.com/sparklemotion/nokogiri/issues/902)
+* (JRuby) JRuby-Nokogiri does not recognise attributes inside namespaces [#1081](https://github.com/sparklemotion/nokogiri/issues/1081)
+* (JRuby) JRuby-Nokogiri has different comment node name [#1080](https://github.com/sparklemotion/nokogiri/issues/1080)
+* (JRuby) JAXPExtensionsProvider / Java 7 / Secure Processing [#1070](https://github.com/sparklemotion/nokogiri/issues/1070)
## 1.6.1 / 2013-12-14
-* Bugfixes
+### Fixed
- * (JRuby) Fix out of memory bug when certain invalid documents are parsed.
- * (JRuby) Fix regression of billion-laughs vulnerability. #586
+* (JRuby) Fix out of memory bug when certain invalid documents are parsed.
+* (JRuby) Fix regression of billion-laughs vulnerability. [#586](https://github.com/sparklemotion/nokogiri/issues/586)
## 1.6.0 / 2013-06-08
@@ -649,9 +1434,9 @@ Now requires libxml >= 2.6.21 (was previously >= 2.6.17).
This release was based on v1.5.10 and 1.6.0.rc1, and contains changes
mentioned in both.
-* Deprecations
+### Deprecations
- * Remove pre 1.9 monitoring from Travis.
+* Remove pre 1.9 monitoring from Travis.
## 1.6.0.rc1 / 2013-04-14
@@ -659,815 +1444,756 @@ mentioned in both.
This release was based on v1.5.9, and so does not contain any fixes
mentioned in the notes for v1.5.10.
-* Notes
+### Notes
- * mini_portile is now a runtime dependency
- * Ruby 1.9.2 and higher now required
+* mini_portile is now a runtime dependency
+* Ruby 1.9.2 and higher now required
-* Features
+### Added
- * (MRI) Source code for libxml 2.8.0 and libxslt 1.2.26 is packaged
- with the gem. These libraries are compiled at gem install time
- unless the environment variable NOKOGIRI_USE_SYSTEM_LIBRARIES is
- set. VERSION_INFO (also `nokogiri -v`) exposes whether libxml was
- compiled from packaged source, or the system library was used.
- * (Windows) libxml upgraded to 2.8.0
+* (MRI) Source code for libxml 2.8.0 and libxslt 1.2.26 is packaged with the gem. These libraries are compiled at gem install time unless the environment variable NOKOGIRI_USE_SYSTEM_LIBRARIES is set. VERSION_INFO (also `nokogiri -v`) exposes whether libxml was compiled from packaged source, or the system library was used.
+* (Windows) libxml upgraded to 2.8.0
-* Deprecations
+### Dependencies
- * Support for Ruby 1.8.7 and prior has been dropped
+* Support for Ruby 1.8.7 and prior has been dropped
## 1.5.11 / 2013-12-14
-* Bugfixes
+### Fixed
- * (JRuby) Fix out of memory bug when certain invalid documents are parsed.
- * (JRuby) Fix regression of billion-laughs vulnerability. #586
+* (JRuby) Fix out of memory bug when certain invalid documents are parsed.
+* (JRuby) Fix regression of billion-laughs vulnerability. [#586](https://github.com/sparklemotion/nokogiri/issues/586)
## 1.5.10 / 2013-06-07
-* Bugfixes
+### Fixed
- * (JRuby) Fix "null document" error when parsing an empty IO in jruby 1.7.3. #883
- * (JRuby) Fix schema validation when XSD has DOCTYPE set to DTD. #912 (Thanks, Patrick Cheng!)
- * (MRI) Fix segfault when there is no default subelement for an HTML node. #917
+* (JRuby) Fix "null document" error when parsing an empty IO in jruby 1.7.3. [#883](https://github.com/sparklemotion/nokogiri/issues/883)
+* (JRuby) Fix schema validation when XSD has DOCTYPE set to DTD. [#912](https://github.com/sparklemotion/nokogiri/issues/912) (Thanks, Patrick Cheng!)
+* (MRI) Fix segfault when there is no default subelement for an HTML node. [#917](https://github.com/sparklemotion/nokogiri/issues/917)
-* Notes
+### Notes
- * Use rb_ary_entry instead of RARRAY_PTR (you know, for Rubinius). #877 (Thanks, Dirkjan Bussink!)
- * Fix TypeError when running tests. #900 (Thanks, Cédric Boutillier!)
+* Use rb_ary_entry instead of RARRAY_PTR (you know, for Rubinius). [#877](https://github.com/sparklemotion/nokogiri/issues/877) (Thanks, Dirkjan Bussink!)
+* Fix TypeError when running tests. [#900](https://github.com/sparklemotion/nokogiri/issues/900) (Thanks, Cédric Boutillier!)
## 1.5.9 / 2013-03-21
-* Bugfixes
+### Fixed
- * Ensure that prefixed attributes are properly namespaced when reparented. #869
- * Fix for inconsistent namespaced attribute access for SVG nested in HTML. #861
- * (MRI) Fixed a memory leak in fragment parsing if nodes are not all subsequently reparented. #856
+* Ensure that prefixed attributes are properly namespaced when reparented. [#869](https://github.com/sparklemotion/nokogiri/issues/869)
+* Fix for inconsistent namespaced attribute access for SVG nested in HTML. [#861](https://github.com/sparklemotion/nokogiri/issues/861)
+* (MRI) Fixed a memory leak in fragment parsing if nodes are not all subsequently reparented. [#856](https://github.com/sparklemotion/nokogiri/issues/856)
## 1.5.8 / 2013-03-19
-* Bugfixes
+### Fixed
- * (JRuby) Fix EmptyStackException thrown by elements with xlink:href attributes and no base_uri #534, #805. (Thanks, Patrick Quinn and Brian Hoffman!)
- * Fixes duplicate attributes issue introduced in 1.5.7. #865
- * Allow use of a prefixed namespace on a root node using Nokogiri::XML::Builder #868
+* (JRuby) Fix EmptyStackException thrown by elements with xlink:href attributes and no base_uri [#534](https://github.com/sparklemotion/nokogiri/issues/534), [#805](https://github.com/sparklemotion/nokogiri/issues/805). (Thanks, Patrick Quinn and Brian Hoffman!)
+* Fixes duplicate attributes issue introduced in 1.5.7. [#865](https://github.com/sparklemotion/nokogiri/issues/865)
+* Allow use of a prefixed namespace on a root node using `Nokogiri::XML::Builder` [#868](https://github.com/sparklemotion/nokogiri/issues/868)
## 1.5.7 / 2013-03-18
-* Features
+### Added
- * Windows support for Ruby 2.0.
+* Windows support for Ruby 2.0.
-* Bugfixes
+### Fixed
- * SAX::Parser.parse_io throw an error when used with lower case encoding. #828
- * (JRuby) Java Nokogiri is finally green (passes all tests) under 1.8 and 1.9 mode. High five everyone. #798, #705
- * (JRuby) Nokogiri::XML::Reader broken (as a pull parser) on jruby - reads the whole XML document. #831
- * (JRuby) JRuby hangs parsing "&". #837
- * (JRuby) JRuby NPE parsing an invalid XML instruction. #838
- * (JRuby) Node#content= incompatibility. #839
- * (JRuby) to_xhtml doesn't print the last slash for self-closing tags in JRuby. #834
- * (JRuby) Adding an EntityReference after a Text node mangles the entity in JRuby. #835
- * (JRuby) JRuby version inconsistency: nil for empty attributes. #818
- * CSS queries for classes (e.g., ".foo") now treat all whitespace identically. #854
- * Namespace behavior cleaned up and made consistent between JRuby and MRI. #846, #801 (Thanks, Michael Klein!)
- * (MRI) SAX parser handles empty processing instructions. #845
+* `SAX::Parser.parse_io` throw an error when used with lower case encoding. [#828](https://github.com/sparklemotion/nokogiri/issues/828)
+* (JRuby) Java Nokogiri is finally green (passes all tests) under 1.8 and 1.9 mode. High five everyone. [#798](https://github.com/sparklemotion/nokogiri/issues/798), [#705](https://github.com/sparklemotion/nokogiri/issues/705)
+* (JRuby) `Nokogiri::XML::Reader` broken (as a pull parser) on jruby - reads the whole XML document. [#831](https://github.com/sparklemotion/nokogiri/issues/831)
+* (JRuby) JRuby hangs parsing "&". [#837](https://github.com/sparklemotion/nokogiri/issues/837)
+* (JRuby) JRuby NPE parsing an invalid XML instruction. [#838](https://github.com/sparklemotion/nokogiri/issues/838)
+* (JRuby) `Node#content=` incompatibility. [#839](https://github.com/sparklemotion/nokogiri/issues/839)
+* (JRuby) to_xhtml doesn't print the last slash for self-closing tags in JRuby. [#834](https://github.com/sparklemotion/nokogiri/issues/834)
+* (JRuby) Adding an `EntityReference` after a Text node mangles the entity in JRuby. [#835](https://github.com/sparklemotion/nokogiri/issues/835)
+* (JRuby) JRuby version inconsistency: nil for empty attributes. [#818](https://github.com/sparklemotion/nokogiri/issues/818)
+* CSS queries for classes (e.g., ".foo") now treat all whitespace identically. [#854](https://github.com/sparklemotion/nokogiri/issues/854)
+* Namespace behavior cleaned up and made consistent between JRuby and MRI. [#846](https://github.com/sparklemotion/nokogiri/issues/846), [#801](https://github.com/sparklemotion/nokogiri/issues/801) (Thanks, Michael Klein!)
+* (MRI) SAX parser handles empty processing instructions. [#845](https://github.com/sparklemotion/nokogiri/issues/845)
## 1.5.6 / 2012-12-19
-* Features
-
- * Improved performance of XML::Document#collect_namespaces. #761 (Thanks, Juergen Mangler!)
- * New callback SAX::Document#processing_instruction (Thanks, Kitaiti Makoto!)
- * Node#native_content= allows setting unescaped node contant. #768
- * XPath lookup with namespaces supports symbol keys. #729 (Thanks, Ben Langfeld.)
- * XML::Node#[]= stringifies values. #729 (Thanks, Ben Langfeld.)
- * bin/nokogiri will process a document from $stdin
- * bin/nokogiri -e will execute a program from the command line
- * (JRuby) bin/nokogiri --version will print the Xerces and NekoHTML versions.
-
-
-* Bugfixes
-
- * Nokogiri now detects XSLT transform errors. #731 (Thanks, Justin Fitzsimmons!)
- * Don't throw an Error when trying to replace top-level text node in DocumentFragment. #775
- * Raise an ArgumentError if an invalid encoding is passed to the SAX parser. #756 (Thanks, Bradley Schaefer!)
- * Prefixed element inconsistency between CRuby and JRuby. #712
- * (JRuby) space prior to xml preamble causes nokogiri to fail parsing. (fixed along with #748) #790
- * (JRuby) Fixed the bug Nokogiri::XML::Node#content inconsistency between Java and C. #794, #797
- * (JRuby) raises INVALID_CHARACTER_ERR exception when EntityReference name starts with '#'. #719
- * (JRuby) doesn't coerce namespaces out of strings on a direct subclass of Node. #715
- * (JRuby) Node#content now renders newlines properly. #737 (Thanks, Piotr Szmielew!)
- * (JRuby) Unknown namespace are ignore when the recover option is used. #748
- * (JRuby) XPath queries for namespaces should not throw exceptions when called twice in a row. #764
- * (JRuby) More consistent (with libxml2) whitespace formatting when emitting XML. #771
- * (JRuby) namespaced attributes broken when appending raw xml to builder. #770
- * (JRuby) Nokogiri::XML::Document#wrap raises undefined method `length' for nil:NilClass when trying to << to a node. #781
- * (JRuby) Fixed "bad file descriptor" bug when closing open file descriptors. #495
- * (JRuby) JRuby/CRuby incompatibility for attribute decorators. #785
- * (JRuby) Issues parsing valid XML with no internal subset in the DTD. #547, #811
- * (JRuby) Issues parsing valid node content when it contains colons. #728
- * (JRuby) Correctly parse the doc type of html documents. #733
- * (JRuby) Include dtd in the xml output when a builder is used with create_internal_subset. #751
- * (JRuby) builder requires textwrappers for valid utf8 in jruby, not in mri. #784
+### Added
+
+* Improved performance of `XML::Document#collect_namespaces`. [#761](https://github.com/sparklemotion/nokogiri/issues/761) (Thanks, Juergen Mangler!)
+* New callback `SAX::Document#processing_instruction` (Thanks, Kitaiti Makoto!)
+* `Node#native_content=` allows setting unescaped node content. [#768](https://github.com/sparklemotion/nokogiri/issues/768)
+* XPath lookup with namespaces supports symbol keys. [#729](https://github.com/sparklemotion/nokogiri/issues/729) (Thanks, Ben Langfeld.)
+* `XML::Node#[]=` stringifies values. [#729](https://github.com/sparklemotion/nokogiri/issues/729) (Thanks, Ben Langfeld.)
+* `bin/nokogiri` will process a document from $stdin
+* `bin/nokogiri -e` will execute a program from the command line
+* (JRuby) `bin/nokogiri --version` will print the Xerces and NekoHTML versions.
+
+
+### Fixed
+
+* Nokogiri now detects XSLT transform errors. [#731](https://github.com/sparklemotion/nokogiri/issues/731) (Thanks, Justin Fitzsimmons!)
+* Don't throw an Error when trying to replace top-level text node in DocumentFragment. [#775](https://github.com/sparklemotion/nokogiri/issues/775)
+* Raise an ArgumentError if an invalid encoding is passed to the SAX parser. [#756](https://github.com/sparklemotion/nokogiri/issues/756) (Thanks, Bradley Schaefer!)
+* Prefixed element inconsistency between CRuby and JRuby. [#712](https://github.com/sparklemotion/nokogiri/issues/712)
+* (JRuby) space prior to xml preamble causes nokogiri to fail parsing. (fixed along with [#748](https://github.com/sparklemotion/nokogiri/issues/748)) [#790](https://github.com/sparklemotion/nokogiri/issues/790)
+* (JRuby) Fixed the bug `Nokogiri::XML::Node#content` inconsistency between Java and C. [#794](https://github.com/sparklemotion/nokogiri/issues/794), [#797](https://github.com/sparklemotion/nokogiri/issues/797)
+* (JRuby) raises INVALID_CHARACTER_ERR exception when EntityReference name starts with '#'. [#719](https://github.com/sparklemotion/nokogiri/issues/719)
+* (JRuby) doesn't coerce namespaces out of strings on a direct subclass of Node. [#715](https://github.com/sparklemotion/nokogiri/issues/715)
+* (JRuby) `Node#content` now renders newlines properly. [#737](https://github.com/sparklemotion/nokogiri/issues/737) (Thanks, Piotr Szmielew!)
+* (JRuby) Unknown namespace are ignore when the recover option is used. [#748](https://github.com/sparklemotion/nokogiri/issues/748)
+* (JRuby) XPath queries for namespaces should not throw exceptions when called twice in a row. [#764](https://github.com/sparklemotion/nokogiri/issues/764)
+* (JRuby) More consistent (with libxml2) whitespace formatting when emitting XML. [#771](https://github.com/sparklemotion/nokogiri/issues/771)
+* (JRuby) namespaced attributes broken when appending raw xml to builder. [#770](https://github.com/sparklemotion/nokogiri/issues/770)
+* (JRuby) `Nokogiri::XML::Document#wrap` raises undefined method `length' for nil:NilClass when trying to << to a node. [#781](https://github.com/sparklemotion/nokogiri/issues/781)
+* (JRuby) Fixed "bad file descriptor" bug when closing open file descriptors. [#495](https://github.com/sparklemotion/nokogiri/issues/495)
+* (JRuby) JRuby/CRuby incompatibility for attribute decorators. [#785](https://github.com/sparklemotion/nokogiri/issues/785)
+* (JRuby) Issues parsing valid XML with no internal subset in the DTD. [#547](https://github.com/sparklemotion/nokogiri/issues/547), [#811](https://github.com/sparklemotion/nokogiri/issues/811)
+* (JRuby) Issues parsing valid node content when it contains colons. [#728](https://github.com/sparklemotion/nokogiri/issues/728)
+* (JRuby) Correctly parse the doc type of html documents. [#733](https://github.com/sparklemotion/nokogiri/issues/733)
+* (JRuby) Include dtd in the xml output when a builder is used with create_internal_subset. [#751](https://github.com/sparklemotion/nokogiri/issues/751)
+* (JRuby) builder requires textwrappers for valid utf8 in jruby, not in mri. [#784](https://github.com/sparklemotion/nokogiri/issues/784)
## 1.5.5 / 2012-06-24
-* Features
+### Added
- * Much-improved support for JRuby in 1.9 mode! Yay!
+* Much-improved support for JRuby in 1.9 mode! Yay!
-* Bugfixes
+### Fixed
- * Regression in JRuby Nokogiri add_previous_sibling (1.5.0 -> 1.5.1) #691 (Thanks, John Shahid!)
- * JRuby unable to create HTML doc if URL arg provided #674 (Thanks, John Shahid!)
- * JRuby raises NullPointerException when given HTML document is nil or empty string. #699
- * JRuby 1.9 error, uncaught throw 'encoding_found', has been fixed. #673
- * Invalid encoding returned in JRuby with US-ASCII. #583
- * XmlSaxPushParser raises IndexOutOfBoundsException when over 512 characters are given. #567, #615
- * When xpath evaluation returns empty NodeSet, decorating NodeSet's base document raises exception. #514
- * JRuby raises exception when xpath with namespace is specified. pull request #681 (Thanks, Piotr Szmielew)
- * JRuby renders nodes without their namespace when subclassing Node. #695
- * JRuby raises NAMESPACE_ERR (org.w3c.dom.DOMException) while instantiating RDF::RDFXML::Writer. #683
- * JRuby is not able to use namespaces in xpath. #493
- * JRuby's Entity resolving should be consistent with C-Nokogiri #704, #647, #703
+* Regression in JRuby Nokogiri add_previous_sibling (1.5.0 -> 1.5.1) [#691](https://github.com/sparklemotion/nokogiri/issues/691) (Thanks, John Shahid!)
+* JRuby unable to create HTML doc if URL arg provided [#674](https://github.com/sparklemotion/nokogiri/issues/674) (Thanks, John Shahid!)
+* JRuby raises NullPointerException when given HTML document is nil or empty string. [#699](https://github.com/sparklemotion/nokogiri/issues/699)
+* JRuby 1.9 error, uncaught throw 'encoding_found', has been fixed. [#673](https://github.com/sparklemotion/nokogiri/issues/673)
+* Invalid encoding returned in JRuby with US-ASCII. [#583](https://github.com/sparklemotion/nokogiri/issues/583)
+* XmlSaxPushParser raises IndexOutOfBoundsException when over 512 characters are given. [#567](https://github.com/sparklemotion/nokogiri/issues/567), [#615](https://github.com/sparklemotion/nokogiri/issues/615)
+* When xpath evaluation returns empty `NodeSet`, decorating `NodeSet`'s base document raises exception. [#514](https://github.com/sparklemotion/nokogiri/issues/514)
+* JRuby raises exception when xpath with namespace is specified. pull request [#681](https://github.com/sparklemotion/nokogiri/issues/681) (Thanks, Piotr Szmielew)
+* JRuby renders nodes without their namespace when subclassing Node. [#695](https://github.com/sparklemotion/nokogiri/issues/695)
+* JRuby raises NAMESPACE_ERR (org.w3c.dom.DOMException) while instantiating `RDF::RDFXML::Writer`. [#683](https://github.com/sparklemotion/nokogiri/issues/683)
+* JRuby is not able to use namespaces in xpath. [#493](https://github.com/sparklemotion/nokogiri/issues/493)
+* JRuby's Entity resolving should be consistent with C-Nokogiri [#704](https://github.com/sparklemotion/nokogiri/issues/704), [#647](https://github.com/sparklemotion/nokogiri/issues/647), [#703](https://github.com/sparklemotion/nokogiri/issues/703)
## 1.5.4 / 2012-06-12
-* Features
+### Added
- * The "nokogiri" script now has more verbose output when passed the `--rng` option. #675 (Thanks, Dan Radez!)
- * Build support on hardened Debian systems that use `-Werror=format-security`. #680.
- * Better build support for systems with pkg-config. #584
- * Better build support for systems with multiple iconv installations.
+* The "nokogiri" script now has more verbose output when passed the `--rng` option. [#675](https://github.com/sparklemotion/nokogiri/issues/675) (Thanks, Dan Radez!)
+* Build support on hardened Debian systems that use `-Werror=format-security`. [#680](https://github.com/sparklemotion/nokogiri/issues/680).
+* Better build support for systems with pkg-config. [#584](https://github.com/sparklemotion/nokogiri/issues/584)
+* Better build support for systems with multiple iconv installations.
-* Bugfixes
+### Fixed
- * Segmentation fault when creating a comment node for a DocumentFragment. #677, #678.
- * Treat '.' as xpath in at() and search(). #690
+* Segmentation fault when creating a comment node for a DocumentFragment. [#677](https://github.com/sparklemotion/nokogiri/issues/677), [#678](https://github.com/sparklemotion/nokogiri/issues/678).
+* Treat '.' as xpath in `at()` and `search()`. [#690](https://github.com/sparklemotion/nokogiri/issues/690)
- * (MRI, Security) Default parse options for XML documents were
- changed to not make network connections during document parsing,
- to avoid XXE vulnerability. #693
+### Security
+
+(MRI) Default parse options for XML documents were changed to not make network connections during document parsing, to avoid XXE vulnerability. [#693](https://github.com/sparklemotion/nokogiri/issues/693)
- To re-enable this behavior, the configuration method `nononet` may
- be called, like this:
+To re-enable this behavior, the configuration method `nononet` may be called, like this:
- Nokogiri::XML::Document.parse(xml) { |config| config.nononet }
+``` ruby
+Nokogiri::XML::Document.parse(xml) { |config| config.nononet }
+```
- Insert your own joke about double-negatives here.
+Insert your own joke about double-negatives here.
## 1.5.3 / 2012-06-01
-* Features
-
- * Support for "prefixless" CSS selectors ~, > and + like jQuery
- supports. #621, #623. (Thanks, David Lee!)
- * Attempting to improve installation on homebrew 0.9 (with regards
- to iconv). Isn't package management convenient?
-
-* Bugfixes
-
- * Custom xpath functions with empty nodeset arguments cause a
- segfault. #634.
- * Nokogiri::XML::Node#css now works for XML documents with default
- namespaces when the rule contains attribute selector without
- namespace.
- * Fixed marshalling bugs around how arguments are passed to (and
- returned from) XSLT custom xpath functions. #640.
- * Nokogiri::XML::Reader#outer_xml is broken in JRuby #617
- * Nokogiri::XML::Attribute on JRuby returns a nil namespace #647
- * Nokogiri::XML::Node#namespace= cannot set a namespace without a
- prefix on JRuby #648
- * (JRuby) 1.9 mode causes dead lock while running rake #571
- * HTML::Document#meta_encoding does not raise exception on docs with
- malformed content-type. #655
- * Fixing segfault related to unsupported encodings in in-context
- parsing on 1.8.7. #643
- * (JRuby) Concurrency issue in XPath parsing. #682
+### Added
+
+* Support for "prefixless" CSS selectors ~, > and + like jQuery supports. [#621](https://github.com/sparklemotion/nokogiri/issues/621), [#623](https://github.com/sparklemotion/nokogiri/issues/623). (Thanks, David Lee!)
+* Attempting to improve installation on homebrew 0.9 (with regards to iconv). Isn't package management convenient?
+
+### Fixed
+
+* Custom xpath functions with empty nodeset arguments cause a segfault. [#634](https://github.com/sparklemotion/nokogiri/issues/634).
+* `Nokogiri::XML::Node#css` now works for XML documents with default namespaces when the rule contains attribute selector without namespace.
+* Fixed marshalling bugs around how arguments are passed to (and returned from) XSLT custom xpath functions. [#640](https://github.com/sparklemotion/nokogiri/issues/640).
+* `Nokogiri::XML::Reader#outer_xml` is broken in JRuby [#617](https://github.com/sparklemotion/nokogiri/issues/617)
+* `Nokogiri::XML::Attribute` on JRuby returns a nil namespace [#647](https://github.com/sparklemotion/nokogiri/issues/647)
+* `Nokogiri::XML::Node#namespace=` cannot set a namespace without a prefix on JRuby [#648](https://github.com/sparklemotion/nokogiri/issues/648)
+* (JRuby) 1.9 mode causes dead lock while running rake [#571](https://github.com/sparklemotion/nokogiri/issues/571)
+* `HTML::Document#meta_encoding` does not raise exception on docs with malformed content-type. [#655](https://github.com/sparklemotion/nokogiri/issues/655)
+* Fixing segfault related to unsupported encodings in in-context parsing on 1.8.7. [#643](https://github.com/sparklemotion/nokogiri/issues/643)
+* (JRuby) Concurrency issue in XPath parsing. [#682](https://github.com/sparklemotion/nokogiri/issues/682)
## 1.5.2 / 2012-03-09
-Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631, #632.
+Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. [#631](https://github.com/sparklemotion/nokogiri/issues/631), [#632](https://github.com/sparklemotion/nokogiri/issues/632).
## 1.5.1 / 2012-03-09
-* Features
-
- * XML::Builder#comment allows creation of comment nodes.
- * CSS searches now support namespaced attributes. #593
- * Java integration feature is added. Now, XML::Document.wrap
- and XML::Document#to_java methods are available.
- * RelaxNG validator support in the `nokogiri` cli utility. #591 (thanks, Dan Radez!)
-
-* Bugfixes
-
- * Fix many memory leaks and segfault opportunities. Thanks, Tim Elliott!
- * extconf searches homebrew paths if homebrew is installed.
- * Inconsistent behavior of Nokogiri 1.5.0 Java #620
- * Inheriting from Nokogiri::XML::Node on JRuby (1.6.4/5) fails #560
- * XML::Attr nodes are not allowed to be added as node children, so an
- exception is raised. #558
- * No longer defensively "pickle" adjacent text nodes on
- Node#add_next_sibling and Node#add_previous_sibling calls. #595.
- * Java version inconsistency: it returns nil for empty attributes #589
- * to_xhtml incorrectly generates
when tag is empty #557
- * Document#add_child now accepts a Node, NodeSet, DocumentFragment,
- or String. #546.
- * Document#create_element now recognizes namespaces containing
- non-word characters (like "SOAP-ENV"). This is mostly relevant to
- users of Builder, which calls Document#create_element for nearly
- everything. #531.
- * File encoding broken in 1.5.0 / jruby / windows #529
- * Java version does not return namespace defs as attrs for ::HTML #542
- * Bad file descriptor with Nokogiri 1.5.0 #495
- * remove_namespace! doesn't work in pure java version #492
- * The Nokogiri Java native build throws a null pointer exception
- when ActiveSupport's .blank? method is called directly on a parsed
- object. #489
- * 1.5.0 Not using correct character encoding #488
- * Raw XML string in XML Builder broken on JRuby #486
- * Nokogiri 1.5.0 XML generation broken on JRuby #484
- * Do not allow multiple root nodes. #550
- * Fixes for custom XPath functions. #605, #606 (thanks, Juan Wajnerman!)
- * Node#to_xml does not override :save_with if it is provided. #505
- * Node#set is a private method (JRuby). #564 (thanks, Nick Sieger!)
- * C14n cleanup and Node#canonicalize (thanks, Ivan Pirlik!) #563
+### Added
+
+* `XML::Builder#comment` allows creation of comment nodes.
+* CSS searches now support namespaced attributes. [#593](https://github.com/sparklemotion/nokogiri/issues/593)
+* Java integration feature is added. Now, `XML::Document.wrap` and `XML::Document#to_java` methods are available.
+* RelaxNG validator support in the `nokogiri` cli utility. [#591](https://github.com/sparklemotion/nokogiri/issues/591) (thanks, Dan Radez!)
+
+### Fixed
+
+* Fix many memory leaks and segfault opportunities. Thanks, Tim Elliott!
+* extconf searches homebrew paths if homebrew is installed.
+* Inconsistent behavior of Nokogiri 1.5.0 Java [#620](https://github.com/sparklemotion/nokogiri/issues/620)
+* Inheriting from `Nokogiri::XML::Node` on JRuby (1.6.4/5) fails [#560](https://github.com/sparklemotion/nokogiri/issues/560)
+* `XML::Attr` nodes are not allowed to be added as node children, so an exception is raised. [#558](https://github.com/sparklemotion/nokogiri/issues/558)
+* No longer defensively "pickle" adjacent text nodes on `Node#add_next_sibling` and `Node#add_previous_sibling` calls. [#595](https://github.com/sparklemotion/nokogiri/issues/595).
+* Java version inconsistency: it returns nil for empty attributes [#589](https://github.com/sparklemotion/nokogiri/issues/589)
+* to_xhtml incorrectly generates `` when tag is empty [#557](https://github.com/sparklemotion/nokogiri/issues/557)
+* `Document#add_child` now accepts a `Node`, `NodeSet`, `DocumentFragment`, or `String`. [#546](https://github.com/sparklemotion/nokogiri/issues/546).
+* `Document#create_element` now recognizes namespaces containing non-word characters (like "SOAP-ENV"). This is mostly relevant to users of Builder, which calls `Document#create_element` for nearly everything. [#531](https://github.com/sparklemotion/nokogiri/issues/531).
+* File encoding broken in 1.5.0 / jruby / windows [#529](https://github.com/sparklemotion/nokogiri/issues/529)
+* Java version does not return namespace defs as attrs for `::HTML` [#542](https://github.com/sparklemotion/nokogiri/issues/542)
+* Bad file descriptor with Nokogiri 1.5.0 [#495](https://github.com/sparklemotion/nokogiri/issues/495)
+* remove_namespace! doesn't work in pure java version [#492](https://github.com/sparklemotion/nokogiri/issues/492)
+* The Nokogiri Java native build throws a null pointer exception when ActiveSupport's .blank? method is called directly on a parsed object. [#489](https://github.com/sparklemotion/nokogiri/issues/489)
+* 1.5.0 Not using correct character encoding [#488](https://github.com/sparklemotion/nokogiri/issues/488)
+* Raw XML string in XML Builder broken on JRuby [#486](https://github.com/sparklemotion/nokogiri/issues/486)
+* Nokogiri 1.5.0 XML generation broken on JRuby [#484](https://github.com/sparklemotion/nokogiri/issues/484)
+* Do not allow multiple root nodes. [#550](https://github.com/sparklemotion/nokogiri/issues/550)
+* Fixes for custom XPath functions. [#605](https://github.com/sparklemotion/nokogiri/issues/605), [#606](https://github.com/sparklemotion/nokogiri/issues/606) (thanks, Juan Wajnerman!)
+* `Node#to_xml` does not override `:save_with` if it is provided. [#505](https://github.com/sparklemotion/nokogiri/issues/505)
+* `Node#set` is a private method (JRuby). [#564](https://github.com/sparklemotion/nokogiri/issues/564) (thanks, Nick Sieger!)
+* C14n cleanup and `Node#canonicalize` (thanks, Ivan Pirlik!) [#563](https://github.com/sparklemotion/nokogiri/issues/563)
## 1.5.0 / 2011-07-01
-* Notes
+### Notes
- * See changelog from 1.4.7
+* See changelog from 1.4.7
-* Features
+### Added
- * extracted sets of Node::SaveOptions into Node::SaveOptions::DEFAULT_{X,H,XH}TML (refactor)
+* extracted sets of `Node::SaveOptions` into `Node::SaveOptions::DEFAULT_{X,H,XH}TML` (refactor)
-* Bugfixes
+### Fixed
- * default output of XML on JRuby is no longer formatted due to
- inconsistent whitespace handling. #415
- * (JRuby) making empty NodeSets with null `nodes` member safe to operate on. #443
- * Fix a bug in advanced encoding detection that leads to partially
- duplicated document when parsing an HTML file with unknown
- encoding.
- * Add support for .
+* default output of XML on JRuby is no longer formatted due to inconsistent whitespace handling. [#415](https://github.com/sparklemotion/nokogiri/issues/415)
+* (JRuby) making empty `NodeSet`s with null `nodes` member safe to operate on. [#443](https://github.com/sparklemotion/nokogiri/issues/443)
+* Fix a bug in advanced encoding detection that leads to partially duplicated document when parsing an HTML file with unknown encoding.
+* Add support for ``.
-## 1.5.0 beta3 / 2010/12/02
+## 1.5.0 beta3 / 2010-12-02
-* Notes
+### Notes
- * JRuby performance tuning
- * See changelog from 1.4.4
+* JRuby performance tuning
+* See changelog from 1.4.4
-* Bugfixes
+### Fixed
- * Node#inner_text no longer returns nil. (JRuby) #264
+* `Node#inner_text` no longer returns nil. (JRuby) [#264](https://github.com/sparklemotion/nokogiri/issues/264)
-## 1.5.0 beta2 / 2010/07/30
+## 1.5.0 beta2 / 2010-07-30
-* Notes
+### Notes
+
+* See changelog from 1.4.3
- * See changelog from 1.4.3
+## 1.5.0 beta1 / 2010-05-22
+
+### Notes
-## 1.5.0 beta1 / 2010/05/22
+* JRuby support is provided by a new pure-java backend.
-* Notes
+### Dependencies
- * JRuby support is provided by a new pure-java backend.
+* Ruby 1.8.6 is deprecated. Nokogiri will install, but official support is ended.
+* LibXML 2.6.16 and earlier are deprecated. Nokogiri will refuse to install.
-* Deprecations
+### Removed
- * Ruby 1.8.6 is deprecated. Nokogiri will install, but official support is ended.
- * LibXML 2.6.16 and earlier are deprecated. Nokogiri will refuse to install.
- * FFI support is removed.
+* FFI support is removed.
## 1.4.7 / 2011-07-01
-* Bugfixes
+### Fixed
- * Fix a bug in advanced encoding detection that leads to partially
- duplicated document when parsing an HTML file with unknown
- encoding. Thanks, Timothy Elliott (@ender672)! #478
+* Fix a bug in advanced encoding detection that leads to partially duplicated document when parsing an HTML file with unknown encoding. Thanks, Timothy Elliott ([@ender672](https://github.com/ender672))! [#478](https://github.com/sparklemotion/nokogiri/issues/478)
## 1.4.6 / 2011-06-19
-* Notes
+### Notes
- * This version is functionally identical to 1.4.5.
- * Ruby 1.8.6 support has been restored.
+* This version is functionally identical to 1.4.5.
+* Ruby 1.8.6 support has been restored.
## 1.4.5 / 2011-05-19
-* New Features
+### Added
- * Nokogiri::HTML::Document#title accessor gets and sets the document title.
- * extracted sets of Node::SaveOptions into Node::SaveOptions::DEFAULT_{X,H,XH}TML (refactor)
- * Raise an exception if a string is passed to Nokogiri::XML::Schema#validate. #406
+* `Nokogiri::HTML::Document#title` accessor gets and sets the document title.
+* extracted sets of `Node::SaveOptions` into `Node::SaveOptions::DEFAULT_{X,H,XH}TML` (refactor)
+* Raise an exception if a string is passed to `Nokogiri::XML::Schema#validate`. [#406](https://github.com/sparklemotion/nokogiri/issues/406)
-* Bugfixes
+### Fixed
- * Node#serialize-and-friends now accepts a SaveOption object as the, erm, save object.
- * Nokogiri::CSS::Parser has-a Nokogiri::CSS::Tokenizer
- * (JRUBY+FFI only) Weak references are now threadsafe. #355
- * Make direct start_element() callback (currently used for
- HTML::SAX::Parser) pass attributes in assoc array, just as
- emulated start_element() callback does. rel. #356
- * HTML::SAX::Parser should call back a block given to parse*() if any, just as XML::SAX::Parser does.
- * Add further encoding detection to HTML parser that libxml2 does not do.
- * Document#remove_namespaces! now handles attributes with namespaces. #396
- * XSLT::Stylesheet#transform no longer segfaults when handed a non-XML::Document. #452
- * XML::Reader no longer segfaults when under GC pressure. #439
+* `Node#serialize`-and-friends now accepts a `SaveOption` object as the, erm, save object.
+* `Nokogiri::CSS::Parser` has-a `Nokogiri::CSS::Tokenizer`
+* (JRUBY+FFI only) Weak references are now threadsafe. [#355](https://github.com/sparklemotion/nokogiri/issues/355)
+* Make direct `start_element()` callback (currently used for `HTML::SAX::Parser`) pass attributes in assoc array, just as emulated `start_element()` callback does. rel. [#356](https://github.com/sparklemotion/nokogiri/issues/356)
+* `HTML::SAX::Parser` should call back a block given to `parse*()` if any, just as `XML::SAX::Parser` does.
+* Add further encoding detection to HTML parser that libxml2 does not do.
+* `Document#remove_namespaces!` now handles attributes with namespaces. [#396](https://github.com/sparklemotion/nokogiri/issues/396)
+* `XSLT::Stylesheet#transform` no longer segfaults when handed a non-`XML::Document`. [#452](https://github.com/sparklemotion/nokogiri/issues/452)
+* `XML::Reader` no longer segfaults when under GC pressure. [#439](https://github.com/sparklemotion/nokogiri/issues/439)
## 1.4.4 / 2010-11-15
-* New Features
-
- * XML::Node#children= sets the node's inner html (much like #inner_html=), but returns the reparent node(s).
- * XSLT supports function extensions. #336
- * XPath bind parameter substitution. #329
- * XML::Reader node type constants. #369
- * SAX Parser context provides line and column information
-
-* Bugfixes
-
- * XML::DTD#attributes returns an empty hash instead of nil when there are no attributes.
- * XML::DTD#{keys,each} now work as expected. #324
- * {XML,HTML}::DocumentFragment.{new,parse} no longer strip leading and trailing whitespace. #319
- * XML::Node#{add_child,add_previous_sibling,add_next_sibling,replace} return a NodeSet when passed a string.
- * Unclosed tags parsed more robustly in fragments. #315
- * XML::Node#{replace,add_previous_sibling,add_next_sibling} edge cases fixed related to libxml's text node merging. #308
- * Fixed a segfault when GC occurs during xpath handler argument marshalling. #345
- * Added hack to Slop decorator to work with previously defined methods. #330
- * Fix a memory leak when duplicating child nodes. #353
- * Fixed off-by-one bug with nth-last-{child,of-type} CSS selectors when NOT using an+b notation. #354
- * Fixed passing of non-namespace attributes to SAX::Document#start_element. #356
- * Workaround for libxml2 in-context parsing bug. #362
- * Fixed NodeSet#wrap on nodes within a fragment. #331
-
-
-## 1.4.3 / 2010/07/28
-
-* New Features
-
- * XML::Reader#empty_element? returns true for empty elements. #262
- * Node#remove_namespaces! now removes namespace *declarations* as well. #294
- * NodeSet#at_xpath, NodeSet#at_css and NodeSet#> do what the corresponding
- methods of Node do.
-
-* Bugfixes
-
- * XML::NodeSet#{include?,delete,push} accept an XML::Namespace
- * XML::Document#parse added for parsing in the context of a document
- * XML::DocumentFragment#inner_html= works with contextual parsing! #298, #281
- * lib/nokogiri/css/parser.y Combined CSS functions + pseudo selectors fixed
- * Reparenting text nodes is safe, even when the operation frees adjacent merged nodes. #283
- * Fixed libxml2 versionitis issue with xmlFirstElementChild et al. #303
- * XML::Attr#add_namespace now works as expected. #252
- * HTML::DocumentFragment uses the string's encoding. #305
- * Fix the CSS3 selector translation rule for the general sibling combinator
- (a.k.a. preceding selector) that incorrectly converted "E ~ F G" to
- "//F//G[preceding-sibling::E]".
-
-
-## 1.4.2 / 2010/05/22
-
-* New Features
-
- * XML::Node#parse will parse XML or HTML fragments with respect to the
- context node.
- * XML::Node#namespaces returns all namespaces defined in the node and all
- ancestor nodes
- (previously did not return ancestors' namespace definitions).
- * Added Enumerable to XML::Node
- * Nokogiri::XML::Schema#validate now uses xmlSchemaValidateFile if a
- filename is passed, which is faster and more memory-efficient. GH #219
- * XML::Document#create_entity will create new EntityDecl objects. GH #174
- * JRuby FFI implementation no longer uses ObjectSpace._id2ref,
- instead using Charles Nutter's rocking Weakling gem.
- * Nokogiri::XML::Node#first_element_child fetch the first child node that is
- an ELEMENT node.
- * Nokogiri::XML::Node#last_element_child fetch the last child node that is
- an ELEMENT node.
- * Nokogiri::XML::Node#elements fetch all children nodes that are ELEMENT
- nodes.
- * Nokogiri::XML::Node#add_child, #add_previous_sibling, #before,
- #add_next_sibling, #after, #inner_html, #swap and #replace all now
- accept a Node, DocumentFragment, NodeSet, or a string containing
- markup.
- * Node#fragment? indicates whether a node is a DocumentFragment.
-
-* Bugfixes
-
- * XML::NodeSet is now always decorated (if the document has decorators).
- GH #198
- * XML::NodeSet#slice gracefully handles offset+length larger than the set
- length. GH #200
- * XML::Node#content= safely unlinks previous content. GH #203
- * XML::Node#namespace= takes nil as a parameter
- * XML::Node#xpath returns things other than NodeSet objects. GH #208
- * XSLT::StyleSheet#transform accepts hashes for parameters. GH #223
- * Psuedo selectors inside not() work. GH #205
- * XML::Builder doesn't break when nodes are unlinked.
- Thanks to vihai! GH #228
- * Encoding can be forced on the SAX parser. Thanks Eugene Pimenov! GH #204
- * XML::DocumentFragment uses XML::Node#parse to determine children.
- * Fixed a memory leak in xml reader. Thanks sdor! GH #244
- * Node#replace returns the new child node as claimed in the
- RDoc. Previously returned +self+.
-
-* Notes
-
- * The Windows gems now bundle DLLs for libxml 2.7.6 and libxslt
- 1.1.26. Prior to this release, libxml 2.7.3 and libxslt 1.1.24
- were bundled.
-
-
-## 1.4.1 / 2009/12/10
-
-* New Features
-
- * Added Nokogiri::LIBXML_ICONV_ENABLED
- * Alias Node#[] to Node#attr
- * XML::Node#next_element added
- * XML::Node#> added for searching a nodes immediate children
- * XML::NodeSet#reverse added
- * Added fragment support to Node#add_child, Node#add_next_sibling,
- Node#add_previous_sibling, and Node#replace.
- * XML::Node#previous_element implemented
- * Rubinius support
- * Ths CSS selector engine now supports :has()
- * XML::NodeSet#filter() was added
- * XML::Node.next= and .previous= are aliases for add_next_sibling and add_previous_sibling. GH #183
-
-* Bugfixes
-
- * XML fragments with namespaces do not raise an exception (regression in 1.4.0)
- * Node#matches? works in nodes contained by a DocumentFragment. GH #158
- * Document should not define add_namespace() method. GH #169
- * XPath queries returning namespace declarations do not segfault.
- * Node#replace works with nodes from different documents. GH #162
- * Adding XML::Document#collect_namespaces
- * Fixed bugs in the SOAP4R adapter
- * Fixed bug in XML::Node#next_element for certain edge cases
- * Fixed load path issue with JRuby under Windows. GH #160.
- * XSLT#apply_to will honor the "output method". Thanks richardlehane!
- * Fragments containing leading text nodes with newlines now parse properly. GH #178.
-
-
-## 1.4.0 / 2009/10/30
-
-* Happy Birthday!
-
-* New Features
-
- * Node#at_xpath returns the first element of the NodeSet matching the XPath
- expression.
- * Node#at_css returns the first element of the NodeSet matching the CSS
- selector.
- * NodeSet#| for unions GH #119 (Thanks Serabe!)
- * NodeSet#inspect makes prettier output
- * Node#inspect implemented for more rubyish document inspecting
- * Added XML::DTD#external_id
- * Added XML::DTD#system_id
- * Added XML::ElementContent for DTD Element content validity
- * Better namespace declaration support in Nokogiri::XML::Builder
- * Added XML::Node#external_subset
- * Added XML::Node#create_external_subset
- * Added XML::Node#create_internal_subset
- * XML Builder can append raw strings (GH #141, patch from dudleyf)
- * XML::SAX::ParserContext added
- * XML::Document#remove_namespaces! for the namespace-impaired
-
-* Bugfixes
-
- * returns nil when HTML documents do not declare a meta encoding tag. GH #115
- * Uses RbConfig::CONFIG['host_os'] to adjust ENV['PATH'] GH #113
- * NodeSet#search is more efficient GH #119 (Thanks Serabe!)
- * NodeSet#xpath handles custom xpath functions
- * Fixing a SEGV when XML::Reader gets attributes for current node
- * Node#inner_html takes the same arguments as Node#to_html GH #117
- * DocumentFragment#css delegates to it's child nodes GH #123
- * NodeSet#[] works with slices larger than NodeSet#length GH #131
- * Reparented nodes maintain their namespace. GH #134
- * Fixed SEGV when adding an XML::Document to NodeSet
- * XML::SyntaxError can be duplicated. GH #148
-
-* Deprecations
-
- * Hpricot compatibility layer removed
-
-
-## 1.3.3 / 2009/07/26
-
-* New Features
-
- * NodeSet#children returns all children of all nodes
-
-* Bugfixes
-
- * Override libxml-ruby's global error handler
- * ParseOption#strict fixed
- * Fixed a segfault when sending an empty string to Node#inner_html= GH #88
- * String encoding is now set to UTF-8 in Ruby 1.9
- * Fixed a segfault when moving root nodes between documents. GH #91
- * Fixed an O(n) penalty on node creation. GH #101
- * Allowing XML documents to be output as HTML documents
+### Added
+
+* `XML::Node#children=` sets the node's inner html (much like #inner_html=), but returns the reparent node(s).
+* XSLT supports function extensions. [#336](https://github.com/sparklemotion/nokogiri/issues/336)
+* XPath bind parameter substitution. [#329](https://github.com/sparklemotion/nokogiri/issues/329)
+* `XML::Reader` node type constants. [#369](https://github.com/sparklemotion/nokogiri/issues/369)
+* SAX Parser context provides line and column information
+
+### Fixed
+
+* `XML::DTD#attributes` returns an empty hash instead of nil when there are no attributes.
+* `XML::DTD#{keys,each}` now work as expected. [#324](https://github.com/sparklemotion/nokogiri/issues/324)
+* `{XML,HTML}::DocumentFragment.{new,parse}` no longer strip leading and trailing whitespace. [#319](https://github.com/sparklemotion/nokogiri/issues/319)
+* `XML::Node#{add_child,add_previous_sibling,add_next_sibling,replace}` return a `NodeSet` when passed a string.
+* Unclosed tags parsed more robustly in fragments. [#315](https://github.com/sparklemotion/nokogiri/issues/315)
+* `XML::Node#{replace,add_previous_sibling,add_next_sibling}` edge cases fixed related to libxml's text node merging. [#308](https://github.com/sparklemotion/nokogiri/issues/308)
+* Fixed a segfault when GC occurs during xpath handler argument marshalling. [#345](https://github.com/sparklemotion/nokogiri/issues/345)
+* Added hack to `Slop` decorator to work with previously defined methods. [#330](https://github.com/sparklemotion/nokogiri/issues/330)
+* Fix a memory leak when duplicating child nodes. [#353](https://github.com/sparklemotion/nokogiri/issues/353)
+* Fixed off-by-one bug with `nth-last-{child,of-type}` CSS selectors when NOT using `an+b` notation. [#354](https://github.com/sparklemotion/nokogiri/issues/354)
+* Fixed passing of non-namespace attributes to `SAX::Document#start_element`. [#356](https://github.com/sparklemotion/nokogiri/issues/356)
+* Workaround for libxml2 in-context parsing bug. [#362](https://github.com/sparklemotion/nokogiri/issues/362)
+* Fixed `NodeSet#wrap` on nodes within a fragment. [#331](https://github.com/sparklemotion/nokogiri/issues/331)
+
+
+## 1.4.3 / 2010-07-28
+
+### Added
+
+* `XML::Reader#empty_element?` returns true for empty elements. [#262](https://github.com/sparklemotion/nokogiri/issues/262)
+* `Node#remove_namespaces!` now removes namespace *declarations* as well. [#294](https://github.com/sparklemotion/nokogiri/issues/294)
+* `NodeSet#at_xpath`, `NodeSet#at_css` and `NodeSet#>` do what the corresponding methods of `Node` do.
+
+### Fixed
+
+* `XML::NodeSet#{include?,delete,push}` accept an `XML::Namespace`
+* `XML::Document#parse` added for parsing in the context of a document
+* `XML::DocumentFragment#inner_html=` works with contextual parsing! [#298](https://github.com/sparklemotion/nokogiri/issues/298), [#281](https://github.com/sparklemotion/nokogiri/issues/281)
+* `lib/nokogiri/css/parser.y` Combined CSS functions + pseudo selectors fixed
+* Reparenting text nodes is safe, even when the operation frees adjacent merged nodes. [#283](https://github.com/sparklemotion/nokogiri/issues/283)
+* Fixed libxml2 versionitis issue with `xmlFirstElementChild` et al. [#303](https://github.com/sparklemotion/nokogiri/issues/303)
+* `XML::Attr#add_namespace` now works as expected. [#252](https://github.com/sparklemotion/nokogiri/issues/252)
+* `HTML::DocumentFragment` uses the string's encoding. [#305](https://github.com/sparklemotion/nokogiri/issues/305)
+* Fix the CSS3 selector translation rule for the general sibling combinator (a.k.a. preceding selector) that incorrectly converted "E ~ F G" to "//F//G[preceding-sibling::E]".
+
+
+## 1.4.2 / 2010-05-22
+
+### Added
+
+* `XML::Node#parse` will parse XML or HTML fragments with respect to the context node.
+* `XML::Node#namespaces` returns all namespaces defined in the node and all ancestor nodes (previously did not return ancestors' namespace definitions).
+* Added `Enumerable` to `XML::Node`
+* `Nokogiri::XML::Schema#validate` now uses xmlSchemaValidateFile if a filename is passed, which is faster and more memory-efficient. GH [#219](https://github.com/sparklemotion/nokogiri/issues/219)
+* `XML::Document#create_entity` will create new `EntityDecl` objects. GH [#174](https://github.com/sparklemotion/nokogiri/issues/174)
+* JRuby FFI implementation no longer uses `ObjectSpace._id2ref`, instead using Charles Nutter's rocking Weakling gem.
+* `Nokogiri::XML::Node#first_element_child` fetch the first child node that is an ELEMENT node.
+* `Nokogiri::XML::Node#last_element_child` fetch the last child node that is an ELEMENT node.
+* `Nokogiri::XML::Node#elements` fetch all children nodes that are ELEMENT nodes.
+* `Nokogiri::XML::Node#add_child`, `#add_previous_sibling`, `#before`, `#add_next_sibling`, `#after`, `#inner_html`, `#swap` and `#replace` all now accept a `Node`, `DocumentFragment`, `NodeSet`, or a string containing markup.
+* `Node#fragment?` indicates whether a node is a `DocumentFragment`.
+
+### Fixed
+
+* `XML::NodeSet` is now always decorated (if the document has decorators). GH [#198](https://github.com/sparklemotion/nokogiri/issues/198)
+* `XML::NodeSet#slice` gracefully handles offset+length larger than the set length. GH [#200](https://github.com/sparklemotion/nokogiri/issues/200)
+* `XML::Node#content=` safely unlinks previous content. GH [#203](https://github.com/sparklemotion/nokogiri/issues/203)
+* `XML::Node#namespace=` takes nil as a parameter
+* `XML::Node#xpath` returns things other than `NodeSet` objects. GH [#208](https://github.com/sparklemotion/nokogiri/issues/208)
+* `XSLT::StyleSheet#transform` accepts hashes for parameters. GH [#223](https://github.com/sparklemotion/nokogiri/issues/223)
+* Psuedo selectors inside `not()` work. GH [#205](https://github.com/sparklemotion/nokogiri/issues/205)
+* `XML::Builder` doesn't break when nodes are unlinked. Thanks to vihai! GH [#228](https://github.com/sparklemotion/nokogiri/issues/228)
+* Encoding can be forced on the SAX parser. Thanks Eugene Pimenov! GH [#204](https://github.com/sparklemotion/nokogiri/issues/204)
+* `XML::DocumentFragment` uses `XML::Node#parse` to determine children.
+* Fixed a memory leak in xml reader. Thanks sdor! GH [#244](https://github.com/sparklemotion/nokogiri/issues/244)
+* `Node#replace` returns the new child node as claimed in the RDoc. Previously returned +self+.
+
+### Notes
+
+* The Windows gems now bundle DLLs for libxml 2.7.6 and libxslt 1.1.26. Prior to this release, libxml 2.7.3 and libxslt 1.1.24 were bundled.
+
+
+## 1.4.1 / 2009-12-10
+
+### Added
+
+* Added `Nokogiri::LIBXML_ICONV_ENABLED`
+* Alias `Node#[]` to `Node#attr`
+* `XML::Node#next_element` added
+* `XML::Node#>` added for searching a nodes immediate children
+* `XML::NodeSet#reverse` added
+* Added fragment support to `Node#add_child`, `Node#add_next_sibling`, `Node#add_previous_sibling`, and `Node#replace`.
+* `XML::Node#previous_element` implemented
+* Rubinius support
+* Ths CSS selector engine now supports `:has()`
+* `XML::NodeSet#filter()` was added
+* `XML::Node.next=` and .previous= are aliases for add_next_sibling and add_previous_sibling. GH [#183](https://github.com/sparklemotion/nokogiri/issues/183)
+
+### Fixed
+
+* XML fragments with namespaces do not raise an exception (regression in 1.4.0)
+* `Node#matches?` works in nodes contained by a `DocumentFragment`. GH [#158](https://github.com/sparklemotion/nokogiri/issues/158)
+* `Document` should not define `add_namespace()` method. GH [#169](https://github.com/sparklemotion/nokogiri/issues/169)
+* `XPath` queries returning namespace declarations do not segfault.
+* `Node#replace` works with nodes from different documents. GH [#162](https://github.com/sparklemotion/nokogiri/issues/162)
+* Adding `XML::Document#collect_namespaces`
+* Fixed bugs in the SOAP4R adapter
+* Fixed bug in `XML::Node#next_element` for certain edge cases
+* Fixed load path issue with JRuby under Windows. GH [#160](https://github.com/sparklemotion/nokogiri/issues/160).
+* `XSLT#apply_to` will honor the "output method". Thanks richardlehane!
+* Fragments containing leading text nodes with newlines now parse properly. GH [#178](https://github.com/sparklemotion/nokogiri/issues/178).
+
+
+## 1.4.0 / 2009-10-30
+
+### Added
+
+* `Node#at_xpath` returns the first element of the `NodeSet` matching the XPath expression.
+* `Node#at_css` returns the first element of the `NodeSet` matching the CSS selector.
+* `NodeSet#|` for unions GH [#119](https://github.com/sparklemotion/nokogiri/issues/119) (Thanks Serabe!)
+* `NodeSet#inspect` makes prettier output
+* `Node#inspect` implemented for more rubyish document inspecting
+* Added `XML::DTD#external_id`
+* Added `XML::DTD#system_id`
+* Added `XML::ElementContent` for DTD Element content validity
+* Better namespace declaration support in `Nokogiri::XML::Builder`
+* Added `XML::Node#external_subset`
+* Added `XML::Node#create_external_subset`
+* Added `XML::Node#create_internal_subset`
+* XML Builder can append raw strings (GH [#141](https://github.com/sparklemotion/nokogiri/issues/141), patch from dudleyf)
+* `XML::SAX::ParserContext` added
+* `XML::Document#remove_namespaces!` for the namespace-impaired
+
+### Fixed
+
+* returns nil when HTML documents do not declare a meta encoding tag. GH [#115](https://github.com/sparklemotion/nokogiri/issues/115)
+* Uses `RbConfig::CONFIG['host_os']` to adjust `ENV['PATH']` GH [#113](https://github.com/sparklemotion/nokogiri/issues/113)
+* `NodeSet#search` is more efficient GH [#119](https://github.com/sparklemotion/nokogiri/issues/119) (Thanks Serabe!)
+* `NodeSet#xpath` handles custom xpath functions
+* Fixing a SEGV when `XML::Reader` gets attributes for current node
+* `Node#inner_html` takes the same arguments as `Node#to_html` GH [#117](https://github.com/sparklemotion/nokogiri/issues/117)
+* `DocumentFragment#css` delegates to it's child nodes GH [#123](https://github.com/sparklemotion/nokogiri/issues/123)
+* `NodeSet#[]` works with slices larger than `NodeSet#length` GH [#131](https://github.com/sparklemotion/nokogiri/issues/131)
+* Reparented nodes maintain their namespace. GH [#134](https://github.com/sparklemotion/nokogiri/issues/134)
+* Fixed SEGV when adding an `XML::Document` to `NodeSet`
+* `XML::SyntaxError` can be duplicated. GH [#148](https://github.com/sparklemotion/nokogiri/issues/148)
+
+### Removed
+
+* Hpricot compatibility layer removed
+
+
+## 1.3.3 / 2009-07-26
+
+### Added
+
+* `NodeSet#children` returns all children of all nodes
+
+### Fixed
+
+* Override libxml-ruby's global error handler
+* `ParseOption#strict` fixed
+* Fixed a segfault when sending an empty string to `Node#inner_html=` GH [#88](https://github.com/sparklemotion/nokogiri/issues/88)
+* String encoding is now set to UTF-8 in Ruby 1.9
+* Fixed a segfault when moving root nodes between documents. GH [#91](https://github.com/sparklemotion/nokogiri/issues/91)
+* Fixed an O(n) penalty on node creation. GH [#101](https://github.com/sparklemotion/nokogiri/issues/101)
+* Allowing XML documents to be output as HTML documents
-* Deprecations
+### Deprecations
- * Hpricot compatibility layer will be removed in 1.4.0
+* Hpricot compatibility layer will be removed in 1.4.0
## 1.3.2 / 2009-06-22
-* New Features
+### Added
- * Nokogiri::XML::DTD#validate will validate your document
+* `Nokogiri::XML::DTD#validate` will validate your document
-* Bugfixes
+### Fixed
- * Nokogiri::XML::NodeSet#search will search top level nodes. GH #73
- * Removed namespace related methods from Nokogiri::XML::Document
- * Fixed a segfault when a namespace was added twice
- * Made nokogiri work with Snow Leopard GH #79
- * Mailing list has moved to: http://groups.google.com/group/nokogiri-talk
- * HTML fragments now correctly handle comments and CDATA blocks. GH #78
- * Nokogiri::XML::Document#clone is now an alias of dup
+* `Nokogiri::XML::NodeSet#search` will search top level nodes. GH [#73](https://github.com/sparklemotion/nokogiri/issues/73)
+* Removed namespace related methods from `Nokogiri::XML::Document`
+* Fixed a segfault when a namespace was added twice
+* Made nokogiri work with Snow Leopard GH [#79](https://github.com/sparklemotion/nokogiri/issues/79)
+* Mailing list has moved to: http://groups.google.com/group/nokogiri-talk
+* HTML fragments now correctly handle comments and CDATA blocks. GH [#78](https://github.com/sparklemotion/nokogiri/issues/78)
+* `Nokogiri::XML::Document#clone` is now an alias of dup
-* Deprecations
+### Deprecations
- * Nokogiri::XML::SAX::Document#start_element_ns is deprecated, please switch
- to Nokogiri::XML::SAX::Document#start_element_namespace
- * Nokogiri::XML::SAX::Document#end_element_ns is deprecated, please switch
- to Nokogiri::XML::SAX::Document#end_element_namespace
+* `Nokogiri::XML::SAX::Document#start_element_ns` is deprecated, please switch to `Nokogiri::XML::SAX::Document#start_element_namespace`
+* `Nokogiri::XML::SAX::Document#end_element_ns` is deprecated, please switch to `Nokogiri::XML::SAX::Document#end_element_namespace`
## 1.3.1 / 2009-06-07
-* Bugfixes
+### Fixed
- * extconf.rb checks for optional RelaxNG and Schema functions
- * Namespace nodes are added to the Document node cache
+* `extconf.rb` checks for optional RelaxNG and Schema functions
+* Namespace nodes are added to the Document node cache
## 1.3.0 / 2009-05-30
-* New Features
-
- * Builder changes scope based on block arity
- * Builder supports methods ending in underscore similar to tagz
- * Nokogiri::XML::Node#<=> compares nodes based on Document position
- * Nokogiri::XML::Node#matches? returns true if Node can be found with
- given selector.
- * Nokogiri::XML::Node#ancestors now returns an Nokogiri::XML::NodeSet
- * Nokogiri::XML::Node#ancestors will match parents against optional selector
- * Nokogiri::HTML::Document#meta_encoding for getting the meta encoding
- * Nokogiri::HTML::Document#meta_encoding= for setting the meta encoding
- * Nokogiri::XML::Document#encoding= to set the document encoding
- * Nokogiri::XML::Schema for validating documents against XSD schema
- * Nokogiri::XML::RelaxNG for validating documents against RelaxNG schema
- * Nokogiri::HTML::ElementDescription for fetching HTML element descriptions
- * Nokogiri::XML::Node#description to fetch the node description
- * Nokogiri::XML::Node#accept implements Visitor pattern
- * bin/nokogiri for easily examining documents (Thanks Yutaka HARA!)
- * Nokogiri::XML::NodeSet now supports more Array and Enumerable operators:
- index, delete, slice, - (difference), + (concatenation), & (intersection),
- push, pop, shift, ==
- * Nokogiri.XML, Nokogiri.HTML take blocks that receive
- Nokogiri::XML::ParseOptions objects
- * Nokogiri::XML::Node#namespace returns a Nokogiri::XML::Namespace
- * Nokogiri::XML::Node#namespace= for setting a node's namespace
- * Nokogiri::XML::DocumentFragment and Nokogiri::HTML::DocumentFragment
- have a sensible API and a more robust implementation.
- * JRuby 1.3.0 support via FFI.
-
-* Bugfixes
-
- * Fixed a problem with nil passed to CDATA constructor
- * Fragment method deals with regular expression characters
- (Thanks Joel!) LH #73
- * Fixing builder scope issues LH #61, LH #74, LH #70
- * Fixed a problem when adding a child could remove the child namespace LH#78
- * Fixed bug with unlinking a node then reparenting it. (GH#22)
- * Fixed failure to catch errors during XSLT parsing (GH#32)
- * Fixed a bug with attribute conditions in CSS selectors (GH#36)
- * Fixed intolerance of HTML attributes without values in Node#before/after/inner_html=. (GH#35)
+### Added
+
+* Builder changes scope based on block arity
+* Builder supports methods ending in underscore similar to tagz
+* `Nokogiri::XML::Node#<=>` compares nodes based on Document position
+* `Nokogiri::XML::Node#matches?` returns true if Node can be found with given selector.
+* `Nokogiri::XML::Node#ancestors` now returns an `Nokogiri::XML::NodeSet`
+* `Nokogiri::XML::Node#ancestors` will match parents against optional selector
+* `Nokogiri::HTML::Document#meta_encoding` for getting the meta encoding
+* `Nokogiri::HTML::Document#meta_encoding=` for setting the meta encoding
+* `Nokogiri::XML::Document#encoding=` to set the document encoding
+* `Nokogiri::XML::Schema` for validating documents against XSD schema
+* `Nokogiri::XML::RelaxNG` for validating documents against RelaxNG schema
+* `Nokogiri::HTML::ElementDescription` for fetching HTML element descriptions
+* `Nokogiri::XML::Node#description` to fetch the node description
+* `Nokogiri::XML::Node#accept` implements Visitor pattern
+* `bin/nokogiri` for easily examining documents (Thanks Yutaka HARA!)
+* `Nokogiri::XML::NodeSet` now supports more Array and Enumerable operators: index, delete, slice, - (difference), + (concatenation), & (intersection), push, pop, shift, ==
+* `Nokogiri.XML`, `Nokogiri.HTML` take blocks that receive `Nokogiri::XML::ParseOptions` objects
+* `Nokogiri::XML::Node#namespace` returns a `Nokogiri::XML::Namespace`
+* `Nokogiri::XML::Node#namespace=` for setting a node's namespace
+* `Nokogiri::XML::DocumentFragment` and `Nokogiri::HTML::DocumentFragment` have a sensible API and a more robust implementation.
+* JRuby 1.3.0 support via FFI.
+
+### Fixed
+
+* Fixed a problem with nil passed to CDATA constructor
+* Fragment method deals with regular expression characters (Thanks Joel!) LH [#73](https://github.com/sparklemotion/nokogiri/issues/73)
+* Fixing builder scope issues LH [#61](https://github.com/sparklemotion/nokogiri/issues/61), LH [#74](https://github.com/sparklemotion/nokogiri/issues/74), LH [#70](https://github.com/sparklemotion/nokogiri/issues/70)
+* Fixed a problem when adding a child could remove the child namespace LH[#78](https://github.com/sparklemotion/nokogiri/issues/78)
+* Fixed bug with unlinking a node then reparenting it. (GH[#22](https://github.com/sparklemotion/nokogiri/issues/22))
+* Fixed failure to catch errors during XSLT parsing (GH[#32](https://github.com/sparklemotion/nokogiri/issues/32))
+* Fixed a bug with attribute conditions in CSS selectors (GH[#36](https://github.com/sparklemotion/nokogiri/issues/36))
+* Fixed intolerance of HTML attributes without values in `Node#{before/after/inner_html=}`. (GH[#35](https://github.com/sparklemotion/nokogiri/issues/35))
## 1.2.3 / 2009-03-22
-* Bugfixes
+### Fixed
- * Fixing bug where a node is passed in to Node#new
- * Namespace should be assigned on DocumentFragment creation. LH #66
- * Nokogiri::XML::NodeSet#dup works GH #10
- * Nokogiri::HTML returns an empty Document when given a blank string GH#11
- * Adding a child will remove duplicate namespace declarations LH #67
- * Builder methods take a hash as a second argument
+* Fixing bug where a node is passed in to `Node#new`
+* Namespace should be assigned on DocumentFragment creation. LH [#66](https://github.com/sparklemotion/nokogiri/issues/66)
+* `Nokogiri::XML::NodeSet#dup` works GH [#10](https://github.com/sparklemotion/nokogiri/issues/10)
+* `Nokogiri::HTML` returns an empty Document when given a blank string GH[#11](https://github.com/sparklemotion/nokogiri/issues/11)
+* Adding a child will remove duplicate namespace declarations LH [#67](https://github.com/sparklemotion/nokogiri/issues/67)
+* Builder methods take a hash as a second argument
## 1.2.2 / 2009-03-14
-* New features
+### Added
- * Nokogiri may be used with soap4r. See XSD::XMLParser::Nokogiri
- * Nokogiri::XML::Node#inner_html= to set the inner html for a node
- * Nokogiri builder interface improvements
- * Nokogiri::XML::Node#swap swaps html for current node (LH #50)
+* Nokogiri may be used with soap4r. See `XSD::XMLParser::Nokogiri`
+* `Nokogiri::XML::Node#inner_html=` to set the inner html for a node
+* Nokogiri builder interface improvements
+* `Nokogiri::XML::Node#swap` swaps html for current node (LH [#50](https://github.com/sparklemotion/nokogiri/issues/50))
-* Bugfixes
+### Fixed
- * Fixed a tag nesting problem in the Builder API (LH #41)
- * Nokogiri::HTML.fragment will properly handle text only nodes (LH #43)
- * Nokogiri::XML::Node#before will prepend text nodes (LH #44)
- * Nokogiri::XML::Node#after will append text nodes
- * Nokogiri::XML::Node#search automatically registers root namespaces (LH #42)
- * Nokogiri::XML::NodeSet#search automatically registers namespaces
- * Nokogiri::HTML::NamedCharacters delegates to libxml2
- * Nokogiri::XML::Node#[] can take a symbol (LH #48)
- * vasprintf for windows updated. Thanks Geoffroy Couprie!
- * Nokogiri::XML::Node#[]= should not encode entities (LH #55)
- * Namespaces should be copied to reparented nodes (LH #56)
- * Nokogiri uses encoding set on the string for default in Ruby 1.9
- * Document#dup should create a new document of the same type (LH #59)
- * Document should not have a parent method (LH #64)
+* Fixed a tag nesting problem in the Builder API (LH [#41](https://github.com/sparklemotion/nokogiri/issues/41))
+* `Nokogiri::HTML.fragment` will properly handle text only nodes (LH [#43](https://github.com/sparklemotion/nokogiri/issues/43))
+* `Nokogiri::XML::Node#before` will prepend text nodes (LH [#44](https://github.com/sparklemotion/nokogiri/issues/44))
+* `Nokogiri::XML::Node#after` will append text nodes
+* `Nokogiri::XML::Node#search` automatically registers root namespaces (LH [#42](https://github.com/sparklemotion/nokogiri/issues/42))
+* `Nokogiri::XML::NodeSet#search` automatically registers namespaces
+* `Nokogiri::HTML::NamedCharacters` delegates to libxml2
+* `Nokogiri::XML::Node#[]` can take a symbol (LH [#48](https://github.com/sparklemotion/nokogiri/issues/48))
+* vasprintf for windows updated. Thanks Geoffroy Couprie!
+* `Nokogiri::XML::Node#[]=` should not encode entities (LH [#55](https://github.com/sparklemotion/nokogiri/issues/55))
+* Namespaces should be copied to reparented nodes (LH [#56](https://github.com/sparklemotion/nokogiri/issues/56))
+* Nokogiri uses encoding set on the string for default in Ruby 1.9
+* `Document#dup` should create a new document of the same type (LH [#59](https://github.com/sparklemotion/nokogiri/issues/59))
+* `Document` should not have a parent method (LH [#64](https://github.com/sparklemotion/nokogiri/issues/64))
## 1.2.1 / 2009-02-23
-* Bugfixes
+### Fixed
- * Fixed a CSS selector space bug
- * Fixed Ruby 1.9 String Encoding (Thanks 角谷さん!)
+* Fixed a CSS selector space bug
+* Fixed Ruby 1.9 String Encoding (Thanks 角谷さん!)
## 1.2.0 / 2009-02-22
-* New features
+### Added
- * CSS search now supports CSS3 namespace queries
- * Namespaces on the root node are automatically registered
- * CSS queries use the default namespace
- * Nokogiri::XML::Document#encoding get encoding used for this document
- * Nokogiri::XML::Document#url get the document url
- * Nokogiri::XML::Node#add_namespace add a namespace to the node LH#38
- * Nokogiri::XML::Node#each iterate over attribute name, value pairs
- * Nokogiri::XML::Node#keys get all attribute names
- * Nokogiri::XML::Node#line get the line number for a node (Thanks Dirkjan Bussink!)
- * Nokogiri::XML::Node#serialize now takes an optional encoding parameter
- * Nokogiri::XML::Node#to_html, to_xml, and to_xhtml take an optional encoding
- * Nokogiri::XML::Node#to_str
- * Nokogiri::XML::Node#to_xhtml to produce XHTML documents
- * Nokogiri::XML::Node#values get all attribute values
- * Nokogiri::XML::Node#write_to writes the node to an IO object with optional encoding
- * Nokogiri::XML::ProcessingInstrunction.new
- * Nokogiri::XML::SAX::PushParser for all your push parsing needs.
+* CSS search now supports CSS3 namespace queries
+* Namespaces on the root node are automatically registered
+* CSS queries use the default namespace
+* `Nokogiri::XML::Document#encoding` get encoding used for this document
+* `Nokogiri::XML::Document#url` get the document url
+* `Nokogiri::XML::Node#add_namespace` add a namespace to the node LH[#38](https://github.com/sparklemotion/nokogiri/issues/38)
+* `Nokogiri::XML::Node#each` iterate over attribute name, value pairs
+* `Nokogiri::XML::Node#keys` get all attribute names
+* `Nokogiri::XML::Node#line` get the line number for a node (Thanks Dirkjan Bussink!)
+* `Nokogiri::XML::Node#serialize` now takes an optional encoding parameter
+* `Nokogiri::XML::Node#to_html`, to_xml, and to_xhtml take an optional encoding
+* `Nokogiri::XML::Node#to_str`
+* `Nokogiri::XML::Node#to_xhtml` to produce XHTML documents
+* `Nokogiri::XML::Node#values` get all attribute values
+* `Nokogiri::XML::Node#write_to` writes the node to an IO object with optional encoding
+* `Nokogiri::XML::ProcessingInstruction.new`
+* `Nokogiri::XML::SAX::PushParser` for all your push parsing needs.
-* Bugfixes
+### Fixed
- * Fixed Nokogiri::XML::Document#dup
- * Fixed header detection. Thanks rubikitch!
- * Fixed a problem where invalid CSS would cause the parser to hang
+* Fixed `Nokogiri::XML::Document#dup`
+* Fixed header detection. Thanks rubikitch!
+* Fixed a problem where invalid CSS would cause the parser to hang
-* Deprecations
+### Deprecations
- * Nokogiri::XML::Node.new_from_str will be deprecated in 1.3.0
+* `Nokogiri::XML::Node.new_from_str` will be deprecated in 1.3.0
-* API Changes
+### Changed
- * Nokogiri::HTML.fragment now returns an XML::DocumentFragment (LH #32)
+* `Nokogiri::HTML.fragment` now returns an XML::DocumentFragment (LH [#32](https://github.com/sparklemotion/nokogiri/issues/32))
## 1.1.1
-* New features
+### Added
- * Added XML::Node#elem?
- * Added XML::Node#attribute_nodes
- * Added XML::Attr
- * XML::Node#delete added.
- * XML::NodeSet#inner_html added.
+* Added `XML::Node#elem?`
+* Added `XML::Node#attribute_nodes`
+* Added `XML::Attr`
+* `XML::Node#delete` added.
+* `XML::NodeSet#inner_html` added.
-* Bugfixes
+### Fixed
- * Not including an HTML entity for \r for HTML nodes.
- * Removed CSS::SelectorHandler and XML::XPathHandler
- * XML::Node#attributes returns an Attr node for the value.
- * XML::NodeSet implements to_xml
+* Not including an HTML entity for \r for HTML nodes.
+* Removed `CSS::SelectorHandler` and `XML::XPathHandler`
+* `XML::Node#attributes` returns an `Attr` node for the value.
+* `XML::NodeSet` implements `to_xml`
## 1.1.0
-* New Features
+### Added
- * Custom XPath functions are now supported. See Nokogiri::XML::Node#xpath
- * Custom CSS pseudo classes are now supported. See Nokogiri::XML::Node#css
- * Nokogiri::XML::Node#<< will add a child to the current node
+* Custom XPath functions are now supported. See `Nokogiri::XML::Node#xpath`
+* Custom CSS pseudo classes are now supported. See `Nokogiri::XML::Node#css`
+* `Nokogiri::XML::Node#<<` will add a child to the current node
-* Bugfixes
+### Fixed
- * Mutex lock on CSS cache access
- * Fixed build problems with GCC 3.3.5
- * XML::Node#to_xml now takes an indentation argument
- * XML::Node#dup takes an optional depth argument
- * XML::Node#add_previous_sibling returns new sibling node.
+* Mutex lock on CSS cache access
+* Fixed build problems with GCC 3.3.5
+* `XML::Node#to_xml` now takes an indentation argument
+* `XML::Node#dup` takes an optional depth argument
+* `XML::Node#add_previous_sibling` returns new sibling node.
## 1.0.7
-* Bugfixes
+### Fixed
- * Fixed memory leak when using Dike
- * SAX parser now parses IO streams
- * Comment nodes have their own class
- * Nokogiri() should delegate to Nokogiri.parse()
- * Prepending rather than appending to ENV['PATH'] on windows
- * Fixed a bug in complex CSS negation selectors
+* Fixed memory leak when using Dike
+* SAX parser now parses IO streams
+* Comment nodes have their own class
+* `Nokogiri()` should delegate to `Nokogiri.parse()`
+* Prepending rather than appending to `ENV['PATH']` on windows
+* Fixed a bug in complex CSS negation selectors
## 1.0.6
-* 5 Bugfixes
+### Fixed
- * XPath Parser raises a SyntaxError on parse failure
- * CSS Parser raises a SyntaxError on parse failure
- * filter() and not() hpricot compatibility added
- * CSS searches via Node#search are now always relative
- * CSS to XPath conversion is now cached
+* XPath Parser raises a `SyntaxError` on parse failure
+* CSS Parser raises a `SyntaxError` on parse failure
+* `filter()` and `not()` hpricot compatibility added
+* CSS searches via `Node#search` are now always relative
+* CSS to XPath conversion is now cached
## 1.0.5
-* Bugfixes
+### Fixed
- * Added mailing list and ticket tracking information to the README.txt
- * Sets ENV['PATH'] on windows if it doesn't exist
- * Caching results of NodeSet#[] on Document
+* Added mailing list and ticket tracking information to the `README.txt`
+* Sets `ENV['PATH']` on windows if it doesn't exist
+* Caching results of `NodeSet#[]` on `Document`
## 1.0.4
-* Bugfixes
+### Fixed
- * Changed memory management from weak refs to document refs
- * Plugged some memory leaks
- * Builder blocks can call methods from surrounding contexts
+* Changed memory management from weak refs to document refs
+* Plugged some memory leaks
+* Builder blocks can call methods from surrounding contexts
## 1.0.3
-* 5 Bugfixes
+### Fixed
- * NodeSet now implements to_ary
- * XML::Document should not implement parent
- * More GC Bugs fixed. (Mike is AWESOME!)
- * Removed RARRAY_LEN for 1.8.5 compatibility. Thanks Shane Hanna.
- * inner_html fixed. (Thanks Yehuda!)
+* `NodeSet` now implements `to_ary`
+* `XML::Document` should not implement parent
+* More GC Bugs fixed. (Mike is AWESOME!)
+* Removed RARRAY_LEN for 1.8.5 compatibility. Thanks Shane Hanna.
+* `inner_html` fixed. (Thanks Yehuda!)
## 1.0.2
-* 1 Bugfix
+### Fixed
- * extconf.rb should not check for frex and racc
+* `extconf.rb` should not check for frex and racc
## 1.0.1
-* 1 Bugfix
+### Fixed
- * Made sure extconf.rb searched libdir and prefix so that ports libxml/ruby
- will link properly. Thanks lucsky!
+* Made sure `extconf.rb` searched libdir and prefix so that ports libxml/ruby will link properly. Thanks lucsky!
## 1.0.0 / 2008-07-13
-* 1 major enhancement
+### Added
- * Birthday!
+* Birthday!
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f61bc1e4e8..192ddce609 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,33 +1,397 @@
-# Issue and Pull Request Guidelines
+# Contributing to Nokogiri
-Thank you for helping make Nokogiri better!
+This doc is intended to be a short introduction on how to modify and maintain Nokogiri.
+
+If you're looking for guidance on filing a bug report or getting support, please visit the ["Getting Help" tutorial](http://www.nokogiri.org/tutorials/getting_help.html) at the [nokogiri.org](http://nokogiri.org) site.
+
+
+## Contents
+
+
+
+
+
+- [Introduction](#introduction)
+- [Code of Conduct](#code-of-conduct)
+- [Some guiding principles of the project](#some-guiding-principles-of-the-project)
+- [Where to start getting involved](#where-to-start-getting-involved)
+- [Submitting Pull Requests](#submitting-pull-requests)
+- [Branch Management and Release Management](#branch-management-and-release-management)
+- [How to set up your local development environment](#how-to-set-up-your-local-development-environment)
+- [How to run the tests](#how-to-run-the-tests)
+- [Style Guide](#style-guide)
+- [How Continuous Integration ("CI") is configured](#how-continuous-integration-ci-is-configured)
+- [Packaging releases](#packaging-releases)
+- [Other utilities](#other-utilities)
+- [Bumping Java dependencies](#bumping-java-dependencies)
+- [Rake tasks](#rake-tasks)
+- [Making a release](#making-a-release)
+
+
+
+## Introduction
+
+Hello there! I'm super excited that you're interested in contributing to Nokogiri. Welcome!
+
+This document is intended only to provide a brief introduction on how to contribute to Nokogiri. It's not a complete specification of everything you need to know, so if you want to know more, I encourage you to reach out to the maintainers via email, twitter, or a new Github issue. We'd love to get to know you a bit better!
## Code of Conduct
Our full Code of Conduct is in [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md).
-For best results, be nice. Remember that Nokogiri maintainers are volunteers, and treat them with respect.
+For best results, be kind. Remember that Nokogiri maintainers are volunteers, and treat them with respect. Do not act entitled to service. Do not be rude. Do not use judgmental or foul language.
+
+
+## Some guiding principles of the project
+
+The top guiding principles, as noted in the README are:
+
+- be secure-by-default by treating all documents as **untrusted** by default
+- be a **thin-as-reasonable layer** on top of the underlying parsers, and don't attempt to fix behavioral differences between the parsers
+
+
+Nokogiri supports both CRuby and JRuby, and has native code specific to each (though much Ruby code is shared between them). Some related secondary principles are:
+
+- Whenever possible, implement the same functionality for both CRuby and JRuby.
+- Whenever possible, implement shared behavior as shared Ruby code (i.e., write as little native code as reasonable).
+- Whenever possible, avoid writing tests that are platform-specific (but if you do, use `skip` to provide an explanation).
+
+Notably, despite all parsers being standards-compliant, there are behavioral inconsistencies between the parsers used in the CRuby and JRuby implementations, and Nokogiri does not and should not attempt to remove these inconsistencies. Instead, we surface these differences in the test suite when they are important/semantic; or we intentionally write tests to depend only on the important/semantic bits (omitting whitespace from regex matchers on results, for example).
+
+Nokogiri is widely used in the Ruby ecosystem, and so extra care should be taken to avoid introducing breaking changes. Please read our [Semantic Versioning Policy](https://nokogiri.org/index.html#semantic-versioning-policy) to understand what we consider to be a breaking change.
+
+
+## Where to start getting involved
+
+Please take a look at our [Issues marked "Help Wanted"](https://github.com/sparklemotion/nokogiri/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22).
+
+Also, [pull requests for documentation improvements are always welcome](#documentation)!
+
+
+## Submitting Pull Requests
+
+Pull requests should be made with `main` as the merge base. See the next section for details.
+
+**Pull requests that introduce behavior change must always contain a test** demonstrating the behavior being introduced, fixed, or changed. These tests should ideally communicate to the maintainers the problem being solved. We will ask you for clarification if we don't understand the problem you're trying to solve.
+
+If the pull request contains a feature or a bugfix, please make sure to create a CHANGELOG entry in the "unreleased" section.
+
+Please do not submit pull requests that make purely cosmetic changes to the code (style, naming, etc.). While we recognize that the code can always be improved, we prefer that you focus on more impactful contributions.
+
+Feel free to push a "work in progress" to take advantage of the feedback loops from CI. But then please indicate that it's still in progress by marking it as a [Draft Pull Request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests).
+
+
+## Branch Management and Release Management
+
+Nokogiri follows SemVer, and some nuances of that policy are spelled out in [Semantic Versioning Policy](https://nokogiri.org/index.html#semantic-versioning-policy).
+
+Development should be happening on `main`, which sets `Nokogiri::VERSION` to a development version of the next minor release (e.g., `"1.14.0.dev"`). All pull requests should have `main` as the merge base.
+
+Patch releases should be made by cherry-picking commits from `main` onto the release branch (e.g., `v1.13.x`) in a pull request labeled `backport`.
+
+
+## How to set up your local development environment
+
+### Basic
+
+``` sh
+git clone --recurse-submodules https://github.com/sparklemotion/nokogiri
+cd nokogiri
+bundle install
+```
+
+
+### Advanced
+
+Please install the latest or previous version of CRuby (e.g., 3.2 or 3.1 as of 2023-01), and a recent version of JRuby. We recommend using `rbenv`, which is used in test scripts when necessary to test gems against multiple rubies.
+
+Please install a system version of libxml2/libxslt (see [Installing Nokogiri](https://nokogiri.org/tutorials/installing_nokogiri.html#installing-using-standard-system-libraries) for details) so that you can test against both the packaged libraries and your system libraries.
+
+We recommend that you install `valgrind` if you can, but it's only necessary for debugging problems so feel free to wait until you need it. (I'm not sure valgrind is easily available on MacOS.)
+
+If you plan to package precompiled native gems, make sure `docker` is installed and is working properly.
+
+
+## How to run the tests
+
+Note that `rake test` does not compile the native extension, and this is intentional (so we can run the test suite against an installed gem). If you're modifying the extension code, please make sure you re-compile each time you run the tests to ensure you're testing your changes.
+
+
+### The short version
+
+``` sh
+bundle exec rake compile test
+```
+
+To run a focused test, use MiniTest's `TESTOPTS`:
+
+``` sh
+bundle exec rake compile test TESTOPTS="-n/test_last_element_child/"
+```
+
+
+### CRuby advanced usage
+
+Test using your system's libraries:
+
+``` sh
+bundle exec rake clean # blow away pre-existing libraries using packaged libs
+bundle exec rake compile test -- --enable-system-libraries
+```
+
+Run performance tests:
+
+``` sh
+bundle exec rake compile test:bench
+```
+
+
+Run tests using valgrind:
+
+``` sh
+bundle exec rake compile test:valgrind
+```
+
+
+Run tests in the debugger:
+
+``` sh
+bundle exec rake compile test:gdb
+# or
+bundle exec rake compile test:lldb
+```
+
+
+Run tests and look for new memory leaks:
+
+``` sh
+bundle exec rake compile test:memcheck
+```
+
+
+Note that by default the test suite will run a major GC after each test completes. This has shown to be useful for localizing some classes of memory bugs, but does slow the suite down. Some variations of the test suite behavior are available (see `test/helper.rb` for more info):
+
+``` sh
+# see failure messages immediately
+NOKOGIRI_TEST_FAIL_FAST=t bundle exec rake compile test
+
+# ordinary GC behavior
+NOKOGIRI_TEST_GC_LEVEL=normal bundle exec rake compile test
+
+# minor GC after each test
+NOKOGIRI_TEST_GC_LEVEL=minor bundle exec rake compile test
+
+# major GC after each test
+NOKOGIRI_TEST_GC_LEVEL=major bundle exec rake compile test
+
+# major GC after each test and GC compaction after every 20 tests
+NOKOGIRI_TEST_GC_LEVEL=compact bundle exec rake compile test
+
+# verify references after compaction after every 20 tests
+# (see https://alanwu.space/post/check-compaction/)
+NOKOGIRI_TEST_GC_LEVEL=verify bundle exec rake compile test
+
+# run with GC "stress mode" on
+NOKOGIRI_TEST_GC_LEVEL=stress bundle exec rake compile test
+```
+
+
+### libxml2 advanced usage
+
+If you want to build Nokogiri against a modified version of libxml2, clone libxml2 to `../libxml2` and then run `scripts/compile-against-libxml2-source`.
+
+That script also takes an optional command to run with the proper environment variables set to use the local libxml2 library, which can be useful when trying to `git bisect` against libxml2. So, for example:
+
+``` sh
+scripts/compile-against-libxml2-source bundle exec rake test
+```
+
+
+### gumbo HTML5 parser
+
+To run the test suite for the gumbo parser:
+
+``` sh
+bundle exec rake gumbo
+```
+
+Please note that additional html5lib tests for Nokogiri's HTML5 parser exist in a submodule. If you haven't checked that submodule out, here's how to do so:
+
+``` sh
+git submodule update --init # test/html5lib-tests
+bundle exec rake compile test
+```
+
+
+## Style Guide
+
+### Documentation
+
+We use `rdoc` to build Nokogiri's documentation. Run `rake rdoc` to build into the `./html` directory, and see the rdoc tasks in [rakelib/rdoc.rake](rakelib/rdoc.rake).
+
+Previously we made some effort to move towards `yard` but that work was stopped (and the decision record can be found at [RFC: convert to use `yard` for documentation](https://github.com/sparklemotion/nokogiri/issues/1996)).
+
+Docstrings should be in `RDoc::Markup` format, though simple docstrings may be in Markdown (using `:markup: markdown`).
+
+If you submit pull requests that improve documentation, **I will happily merge them** and credit you in the CHANGELOG.
+
+Some guidelines (see [lib/nokogiri/xml/node.rb](lib/nokogiri/xml/node.rb) and [ext/nokogiri/xml/node.c](ext/nokogiri/xml/node.c) for examples):
+
+- Use `:call-seq:` to ...
+ - note the return type of the method whenever possible, e.g. `:call-seq: upcase(name) → String`
+ - name all the aliases of a method
+ - indicate block/yield usage of a method
+- Briefly explain the purpose of the method, what it returns, and what side effects it has
+- Use a `[Parameters]` definition to note the expected types of all the parameters as a bulleted list
+- Use a `[Returns]` definition to note the return type
+- Use a `[Yields]` definition to note the block parameters
+- Use a `⚠` character to warn the user about tricky usage
+- Use a `💡` character to call attention to important notes
+- `See also:` should be used to call out related methods
+- `Since` should be used to indicate the version in which the code was introduced
+- Prefer to **show** nuanced behavior in code examples, rather than try to explain it in prose.
+
+
+### Code
+
+I don't feel very strongly about code style, but this project follows [Shopify's Ruby Style Guide](https://shopify.github.io/ruby-style-guide/), and for C and Java code the project uses the `astyle` configuration laid out in `./rakelib/format.rake`.
+
+You can auto-format the C, Java, and Ruby code with `rake format`.
+
+There are some pending Rubocop rules in `.rubocop_todo.yml`. If you'd like to fix them up, I will happily merge your pull request.
+
+No, I don't want to debate any of the style choices.
+
+
+## How Continuous Integration ("CI") is configured
+
+The bulk of CI is running in Github Actions since May 2021: https://github.com/sparklemotion/nokogiri/actions
+
+However, we also run tests against 32-bit windows (which aren't supported by GA as of this writing) in Appveyor: https://ci.appveyor.com/project/flavorjones/nokogiri
+
+A known hole in CI coverage is the lack native gem tests for arm64-darwin.
+
+
+### Coverage
+
+The `ci.yml` pipeline includes jobs to:
+
+- basic security sanity check and formatting check, using Rubocop
+- fast feedback for obvious failures: run against system libraries on vanilla ubuntu
+- run the Gumbo parser tests on ubuntu, macos, and windows
+- run on all supported versions of CRuby:
+ - once with packaged libraries
+ - once with system libraries
+ - once on valgrind (to look for memory bugs)
+- run the test suite looking for new memory leaks (using ruby_memcheck)
+- run on JRuby
+- run on TruffleRuby
+- run on a Musl (Alpine) system:
+ - against system libraries
+ - with valgrind using packaged libraries
+- run with libxml-ruby loaded (because this can interact with libxml2 in conflicting ways)
+ - against system libraries
+ - with valgrind using packaged libraries
+- build a "ruby" platform gem
+ - install and test on linux, macos, and windows
+- build native gems
+ - install and test against all supported versions of CRuby
+ - install and test on a variety of linux, macos, and windows systems
+- build a jruby gem, install and test it
+
+The `upstream.yml` pipeline includes jobs to:
+
+- run against libxml2 and libxslt head (linux), including a valgrind check
+- run against CRuby head (linux, windows, macos) including a valgrind check
+- run against JRuby head
+- run html5lib-tests from that project's `origin/master`
+
+The `downstream.yml` pipeline includes jobs to run notable downstream dependents against Nokogiri `main`.
+
+The `generate-ci-images.yml` pipeline builds some containers used by the other pipelines once a week. This is primarily an optimization to make sure system packages (like `libxml2-dev` and `valgrind`) are already installed. See `oci-images/nokogiri-test/` for details on what's in these containers.
+
+
+### Valgrind and `ruby_memcheck`
+
+We rely heavily on Valgrind and [`ruby_memcheck`](https://github.com/Shopify/ruby_memcheck) to catch memory bugs by running in combination with every version of CRuby.
+
+We use suppressions primarily to quiet known small memory leaks or quirks of certain Ruby versions. See the files in the `/suppressions` directory and `/rakelib/test.rake` for more information.
+
+
+### Benchmark / Performance tests
+
+A separate suite, `test:bench`, can be run to ensure a few performance expectations. As of 2022-02 this suite is small, but we can grow it over time. These tests are run in CI on CRuby and JRuby.
+
+These tests should use `Nokogiri::TestBenchmark` as the base class, and be in a file matching the glob `test/**/bench_*.rb`.
+
+
+### Helpful hints when writing new CI jobs
+
+- Always checkout the source code **including submodules** (for the html5lib tests)
+- When testing packaged libraries (not system libraries), cache either `ports/` (for compiled libraries) or `ports/archives/` (for just tarballs)
+ - note that `libgumbo` is built outside of `ports/` to allow us to do this caching safely
+
+
+## Packaging releases
+
+As a prerequisite please make sure you have `docker` correctly installed, to build native (precompiled) gems.
+
+Run `scripts/build-gems` which will package gems for all supported platforms, and run some basic sanity tests on those packages using `scripts/test-gem-set`, `scripts/test-gem-file-contents`, and `scripts/test-gem-installation`.
+
+See [Making a release](#making-a-release) below for the checklist.
+
+
+## Other utilities
+
+`scripts/test-exported-symbols` checks the compiled `nokogiri.so` library for surprising exported symbols. This script likely only works on Linux, sorry.
+
+`scripts/test-nokogumbo-compatibility` is used by CI to ensure that Nokogumbo installs correctly against the currently-installed version of Nokogiri. Nokogumbo receives this extra care because it compiles against Nokogiri's and libxml2's header files, and makes assumptions about what symbols are exported by Nokogiri's extension library.
+
+`scripts/files-modified-by-open-prs` is a hack to see what files are being proposed to change in the set of open pull requests. This might be useful if you're thinking about radically changing a file, to be aware of what merge conflicts might result. This could probably be a rake task.
+
+There's a `Vagrantfile` in the project root which I've used once or twice to try to reproduce problems non-Linux systems (like OpenBSD). It's not well-maintained so YMMV.
+
+
+## Bumping Java dependencies
+
+Java dependencies, in the form of `.jar` files, are all vendored as part of the `java` platform gem.
-Do not act entitled to service. Do not be rude. Do not use judgmental or foul language.
+We use [`jar-dependencies`](https://github.com/mkristian/jar-dependencies) as a development dependency to manage the project's Java dependencies. Note, however, that we use our own fork of NekoDTD that lives at https://github.com/sparklemotion/nekodtd
-The maintainers reserve the right to delete comments that are rude, or that contain foul language. The maintainers reserve the right to delete comments that they deem harassing or offensive.
+To modify or add a dependency, a few things needs to be in sync:
+- `nokogiri.gemspec`: `spec.requirements` need to specify the maven group Id, artifact ID, and version
+- `nokogiri.gemspec`: `spec.files` need to include the jar files
+- git: the jar files under `lib/nokogiri/jruby/` need to be committed to git
+- `lib/nokogiri/jruby/nokogiri_jars.rb`: needs to include all the jars
-## Issues
+A quick summary of what this looks like for you, the developer:
-Please read the ["Getting Help" tutorial](http://www.nokogiri.org/tutorials/getting_help.html) at the [nokogiri.org](http://nokogiri.org) site.
+1. edit the `requirements` in the gemspec
+2. run `bundle exec rake vendor_jars` which updates everything under `lib/nokogiri/jruby`
+3. run `bundle exec rake check_manifest` and if necessary update the gemspec `files`
+4. make sure to check everything under `lib/nokogiri/jruby` into git, including the jar files
-If you're reporting an issue, it must contain:
-* Example code that reproduces the **observed** behavior.
-* An explanation of what the **expected** behavior is.
+## Rake tasks
-That's it. If you don't provide that information, we'll ask you for it, tag the story "needs more information", and then after a time will close it if the information isn't provided.
+The `Rakefile` used to be a big fat mess. It's now decomposed into a small set of files in `/rakelib`. If you've got a new rake task you'd like to introduce, please consider whether it belongs in one of the existing concerns, or needs a new file. Please don't add it to `Rakefile` without compelling reasons.
-## Pull Requests
+## Making a release
-Pull requests must always contain a test to prevent regressions. Preferably, the test should demonstrate the __intent__ of the code.
+A quick checklist:
-We may ask you for clarification if we don't understand the intent of the change.
+- [ ] make sure CI is green!
+- [ ] update `CHANGELOG.md` and `lib/nokogiri/version/constant.rb`
+- [ ] create a git tag
+- [ ] run `scripts/build-gems` and make sure it completes and all the tests pass
+- [ ] `for g in gems/*.gem ; do gem push $g ; done`
+- [ ] create a release at https://github.com/sparklemotion/nokogiri/releases and provide sha2 checksums
+- if security-related,
+ - [ ] publish a GHSA
+ - [ ] email ruby-security-ann@googlegroups.com and ruby-talk@ruby-lang.org
+ - [ ] submit a PR to https://github.com/rubysec/ruby-advisory-db
+- [ ] update nokogiri.org
+- [ ] bump `lib/nokogiri/version/constant.rb` to a prerelease version like `v1.14.0.dev`
diff --git a/C_CODING_STYLE.rdoc b/C_CODING_STYLE.rdoc
deleted file mode 100644
index 83f8182a9b..0000000000
--- a/C_CODING_STYLE.rdoc
+++ /dev/null
@@ -1,33 +0,0 @@
-= C/C++ mode style for Nokogiri
-
-Please don't propose commits that only change whitespace. However, if your
-commit touches a function or section that is not using MRI Ruby conventions,
-feel free to update whitespace in the surrounding code.
-
-
-= WHITESPACE:
-
-* indent level: 2
-* indent type: Always spaces
-* line Breaks: LF
-
-This style can be automatically applied by running:
-
- astyle --indent=spaces=2 --style=1tbs --keep-one-line-blocks $(ack -f --type=cpp --type=cc ext/nokogiri)
-
-
-= FUNCTION DECLARATION:
-
-ANSI C style:
-
- type name(args)
- {
- declarations
-
- code
- }
-
-= SOURCES:
-
-* <3<3<3
-
diff --git a/Gemfile b/Gemfile
index 0fbae5913b..0bd1bdc1a3 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,24 +1,44 @@
-# -*- ruby -*-
-
-# DO NOT EDIT THIS FILE. Instead, edit Rakefile, and run `rake bundler:gemfile`.
-
-source "https://rubygems.org/"
-
-gem "mini_portile2", "~>2.4.0"
-
-gem "concourse", "~>0.24", :group => [:development, :test]
-gem "hoe-bundler", "~>1.2", :group => [:development, :test]
-gem "hoe-debugging", "~>2.0", :group => [:development, :test]
-gem "hoe-gemspec", "~>1.0", :group => [:development, :test]
-gem "hoe-git", "~>1.6", :group => [:development, :test]
-gem "minitest", "~>5.8", :group => [:development, :test]
-gem "racc", "~>1.4.14", :group => [:development, :test]
-gem "rake", "~>12.0", :group => [:development, :test]
-gem "rake-compiler", "~>1.0.3", :group => [:development, :test]
-gem "rake-compiler-dock", "~>0.7.0", :group => [:development, :test]
-gem "rexical", "~>1.0.5", :group => [:development, :test]
-gem "simplecov", "~>0.16", :group => [:development, :test]
-gem "rdoc", ">=4.0", "<7", :group => [:development, :test]
-gem "hoe", "~>3.17", :group => [:development, :test]
-
-# vim: syntax=ruby
+# frozen_string_literal: true
+
+source "https://rubygems.org"
+
+gemspec
+
+group :development do
+ # bootstrapping
+ gem "bundler", "~> 2.3"
+ gem "rake", "= 13.0.6"
+
+ # building extensions
+ gem "rake-compiler", "= 1.2.1"
+ gem "rake-compiler-dock", "= 1.3.0"
+
+ # documentation
+ gem "hoe-markdown", "= 1.4.0"
+
+ # parser generator
+ gem "rexical", "= 1.0.7"
+
+ # tests
+ gem "minitest", "5.17.0"
+ gem "minitest-reporters", "= 1.5.0"
+ gem "ruby_memcheck", "1.2.0" unless RUBY_PLATFORM == "java"
+ gem "simplecov", "= 0.21.2"
+ gem "rubyzip", "~> 2.3.2"
+
+ # rubocop
+ if Gem::Requirement.new("~> 3.0").satisfied_by?(Gem::Version.new(RUBY_VERSION))
+ gem "rubocop", "1.44.1"
+ gem "rubocop-minitest", "0.27.0"
+ gem "rubocop-performance", "1.15.2"
+ gem "rubocop-rake", "= 0.6.0"
+ gem "rubocop-shopify", "2.10.1"
+ end
+end
+
+# If Psych doesn't build, you can disable this group locally by running
+# `bundle config set --local without rdoc`
+# Then re-run `bundle install`.
+group :rdoc do
+ gem "rdoc", "6.5.0"
+end
diff --git a/LICENSE-DEPENDENCIES.md b/LICENSE-DEPENDENCIES.md
index 336ab62c54..8dc5e857fc 100644
--- a/LICENSE-DEPENDENCIES.md
+++ b/LICENSE-DEPENDENCIES.md
@@ -1,266 +1,138 @@
-## Vendored Dependency Licenses
+# Vendored Dependency Licenses
-Nokogiri ships with some third party dependencies, which are listed
-here along with their licenses.
+Nokogiri ships with some third party dependencies, which are listed here along with their licenses.
-Note that this document is broken into three sections, each of which
-will apply to different platform releases of Nokogiri:
+Note that this document is broken into multiple sections, each of which describes the dependencies of a different "platform release" of Nokogiri.
-1. default platform release
-2. `java` platform release
-3. binary windows platform releases (`x86-mingw32` and `x64-mingw32`)
+
-It's encouraged for anyone consuming this file via license-tracking
-software to understand which dependencies are used by your particular
-software, so as not to misinterpret the contents of this file.
+
-In particular, I'm sure somebody's lawyer, somewhere, is going to
-freak out that the LGPL appears in this file; and so I'd like to take
-special note that the dependency covered by LGPL, `libiconv`, is only
-being redistributed in the binary Windows platform release. It's not
-present in any non-Windows releases.
+- [Platform Releases](#platform-releases)
+ * [Default platform release ("ruby")](#default-platform-release-ruby)
+ * [Native LinuxⓇ platform releases ("x86_64-linux", "arm64-linux", "aarch64-linux", and "arm-linux")](#native-linux%E2%93%A1-platform-releases-x86_64-linux-arm64-linux-aarch64-linux-and-arm-linux)
+ * [Native Darwin (macOSⓇ) platform releases ("x86_64-darwin" and "arm64-darwin")](#native-darwin-macos%E2%93%A1-platform-releases-x86_64-darwin-and-arm64-darwin)
+ * [Native WindowsⓇ platform releases ("x86-mingw32" and "x64-mingw32")](#native-windows%E2%93%A1-platform-releases-x86-mingw32-and-x64-mingw32)
+ * [JavaⓇ (JRuby) platform release ("java")](#java%E2%93%A1-jruby-platform-release-java)
+- [Appendix: Dependencies' License Texts](#appendix-dependencies-license-texts)
+ * [libgumbo](#libgumbo)
+ * [libxml2](#libxml2)
+ * [libxslt](#libxslt)
+ * [zlib](#zlib)
+ * [libiconv](#libiconv)
+ * [isorelax:isorelax](#isorelaxisorelax)
+ * [net.sf.saxon:Saxon-HE](#netsfsaxonsaxon-he)
+ * [net.sourceforge.htmlunit:neko-htmlunit](#netsourceforgehtmlunitneko-htmlunit)
+ * [nu.validator:jing](#nuvalidatorjing)
+ * [org.nokogiri:nekodtd](#orgnokogirinekodtd)
+ * [xalan:serializer and xalan:xalan](#xalanserializer-and-xalanxalan)
+ * [xerces:xercesImpl](#xercesxercesimpl)
+ * [xml-apis:xml-apis](#xml-apisxml-apis)
------
+
-## default platform release
+Anyone consuming this file via license-tracking software should endeavor to understand which gem file you're downloading and using, so as not to misinterpret the contents of this file and the licenses of the software being distributed.
-### libxml2
+You can double-check the dependencies in your gem file by examining the output of `nokogiri -v` after installation, which will emit the complete set of libraries in use (for versions `>= 1.11.0.rc4`).
-MIT
+In particular, I'm sure somebody's lawyer, somewhere, is going to freak out that the LGPL appears in this file; and so I'd like to take special note that the dependency covered by LGPL, `libiconv`, is only being redistributed in the native Windows and native Darwin platform releases. It's not present in default, JavaⓇ, or native LinuxⓇ releases.
-http://xmlsoft.org/
- Except where otherwise noted in the source code (e.g. the files hash.c,
- list.c and the trio files, which are covered by a similar licence but
- with different Copyright notices) all the files are:
-
- Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved.
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is fur-
- nished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
- NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-
+## Platform Releases
-### libxslt
+### Default platform release ("ruby")
-MIT
+The default platform release distributes the following dependencies in source form:
-http://xmlsoft.org/libxslt/
+* [libxml2](#libxml2)
+* [libxslt](#libxslt)
+* [libgumbo](#libgumbo)
- Licence for libxslt except libexslt
- ----------------------------------------------------------------------
- Copyright (C) 2001-2002 Daniel Veillard. All Rights Reserved.
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is fur-
- nished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
- NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- DANIEL VEILLARD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
- NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- Except as contained in this notice, the name of Daniel Veillard shall not
- be used in advertising or otherwise to promote the sale, use or other deal-
- ings in this Software without prior written authorization from him.
-
- ----------------------------------------------------------------------
-
- Licence for libexslt
- ----------------------------------------------------------------------
- Copyright (C) 2001-2002 Thomas Broyer, Charlie Bozeman and Daniel Veillard.
- All Rights Reserved.
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is fur-
- nished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
- NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
- NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- Except as contained in this notice, the name of the authors shall not
- be used in advertising or otherwise to promote the sale, use or other deal-
- ings in this Software without prior written authorization from him.
- ----------------------------------------------------------------------
-
-## `java` platform release
+This distribution can be identified by inspecting the included Gem::Specification, which will have the value "ruby" for its "platform" attribute.
-### isorelax
-MIT
+### Native LinuxⓇ platform releases ("x86_64-linux", "arm64-linux", "aarch64-linux", and "arm-linux")
-http://iso-relax.sourceforge.net/
+The native LinuxⓇ platform release distributes the following dependencies in source form:
- Copyright (c) 2001-2002, SourceForge ISO-RELAX Project (ASAMI
- Tomoharu, Daisuke Okajima, Kohsuke Kawaguchi, and MURATA Makoto)
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+* [libxml2](#libxml2)
+* [libxslt](#libxslt)
+* [libgumbo](#libgumbo)
+* [zlib](#zlib)
+This distribution can be identified by inspecting the included Gem::Specification, which will have a value similar to "x86_64-linux" or "arm64-linux" for its "platform.cpu" attribute.
-### jing
-BSD-3-Clause
+### Native Darwin (macOSⓇ) platform releases ("x86_64-darwin" and "arm64-darwin")
-http://www.thaiopensource.com/relaxng/jing.html
+The native Darwin platform release distributes the following dependencies in source form:
- Copyright (c) 2001-2003 Thai Open Source Software Center Ltd
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
-
- * Neither the name of the Thai Open Source Software Center Ltd nor
- the names of its contributors may be used to endorse or promote
- products derived from this software without specific prior
- written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
+* [libxml2](#libxml2)
+* [libxslt](#libxslt)
+* [libgumbo](#libgumbo)
+* [zlib](#zlib)
+* [libiconv](#libiconv)
-
-### nekodtd
+This distribution can be identified by inspecting the included Gem::Specification, which will have a value similar to "x86_64-darwin" or "arm64-darwin" for its "platform.cpu" attribute. Darwin is also known more familiarly as "OSX" or "macOSⓇ" and is the operating system for many AppleⓇ computers.
-Apache 1.0-derived
-https://people.apache.org/~andyc/neko/doc/dtd/
+### Native WindowsⓇ platform releases ("x86-mingw32" and "x64-mingw32")
- The CyberNeko Software License, Version 1.0
-
- (C) Copyright 2002-2005, Andy Clark. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
- 3. The end-user documentation included with the redistribution,
- if any, must include the following acknowledgment:
- "This product includes software developed by Andy Clark."
- Alternately, this acknowledgment may appear in the software itself,
- if and wherever such third-party acknowledgments normally appear.
-
- 4. The names "CyberNeko" and "NekoHTML" must not be used to endorse
- or promote products derived from this software without prior
- written permission. For written permission, please contact
- andyc@cyberneko.net.
-
- 5. Products derived from this software may not be called "CyberNeko",
- nor may "CyberNeko" appear in their name, without prior written
- permission of the author.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS
- BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- ====================================================================
-
- This license is based on the Apache Software License, version 1.1.
-
-### nekohtml
+The native WindowsⓇ platform release distributes the following dependencies in source form:
+
+* [libxml2](#libxml2)
+* [libxslt](#libxslt)
+* [libgumbo](#libgumbo)
+* [zlib](#zlib)
+* [libiconv](#libiconv)
+
+This distribution can be identified by inspecting the included Gem::Specification, which will have a value similar to "x64-mingw32" or "x86-mingw32" for its "platform.cpu" attribute.
+
+
+### JavaⓇ (JRuby) platform release ("java")
+
+The Java platform release distributes the following dependencies as compiled jar files:
+
+* [isorelax:isorelax](#isorelaxisorelax)
+* [net.sf.saxon:Saxon-HE](#netsfsaxonsaxon-he)
+* [net.sourceforge.htmlunit:neko-htmlunit](#netsourceforgehtmlunitneko-htmlunit)
+* [nu.validator:jing](#nuvalidatorjing)
+* [org.nokogiri:nekodtd](#orgnokogirinekodtd)
+* [xalan:serializer and xalan:xalan](#xalanserializer-and-xalanxalan)
+* [xerces:xercesImpl](#xercesxercesimpl)
+* [xml-apis:xml-apis](#xml-apisxml-apis)
+
+This distribution can be identified by inspecting the included Gem::Specification, which will have the value "java" for its "platform.os" attribute.
+
+
+## Appendix: Dependencies' License Texts
+
+This section contains a subsection for each potentially-distributed dependency, which includes the name of the license and the license text.
+
+Please see previous sections to understand which of these potential dependencies is actually distributed in the gem file you're downloading and using.
+
+
+### libgumbo
Apache 2.0
-http://nekohtml.sourceforge.net/
+https://github.com/sparklemotion/nokogiri/blob/main/gumbo-parser/src/README.md
+
-
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
-
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
+
1. Definitions.
-
+
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
-
+
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
-
+
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
@@ -268,24 +140,24 @@ http://nekohtml.sourceforge.net/
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
-
+
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
-
+
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
-
+
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
-
+
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
-
+
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
@@ -293,7 +165,7 @@ http://nekohtml.sourceforge.net/
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
-
+
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
@@ -307,18 +179,18 @@ http://nekohtml.sourceforge.net/
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
-
+
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
-
+
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
-
+
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
@@ -334,24 +206,24 @@ http://nekohtml.sourceforge.net/
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
-
+
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
-
+
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
-
+
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
-
+
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
-
+
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
@@ -368,14 +240,14 @@ http://nekohtml.sourceforge.net/
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
-
+
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
-
+
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
@@ -383,12 +255,12 @@ http://nekohtml.sourceforge.net/
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
-
+
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
-
+
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
@@ -398,7 +270,7 @@ http://nekohtml.sourceforge.net/
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
-
+
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
@@ -410,7 +282,7 @@ http://nekohtml.sourceforge.net/
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
-
+
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
@@ -421,680 +293,101 @@ http://nekohtml.sourceforge.net/
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
-
+
END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-### xalan
-Apache 2.0
-https://xml.apache.org/xalan-j/
+### libxml2
-covers xalan.jar and serializer.jar
+MIT
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-
-### xerces
+http://xmlsoft.org/
-Apache 2.0
+ Except where otherwise noted in the source code (e.g. the files hash.c,
+ list.c and the trio files, which are covered by a similar licence but
+ with different Copyright notices) all the files are:
-https://xerces.apache.org/xerces2-j/
+ Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved.
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-
-### xml-apis
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is fur-
+ nished to do so, subject to the following conditions:
-Apache 2.0
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
-https://xerces.apache.org/xml-commons/
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+ NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
- Unless otherwise noted all files in XML Commons are covered under the
- Apache License Version 2.0. Please read the LICENSE and NOTICE files.
-
- XML Commons contains some software and documentation that is covered
- under a number of different licenses. This applies particularly to the
- xml-commons/java/external/ directory. Most files under
- xml-commons/java/external/ are covered under their respective
- LICENSE.*.txt files; see the matching README.*.txt files for
- descriptions.
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-
-## binary windows release
-
-NOTE: these libraries are redistributed ONLY with the binary
-cross-compiled Windows platform version of Nokogiri, both x86-mingw32
-and x64-mingw32.
+### libxslt
+
+MIT
+
+http://xmlsoft.org/libxslt/
+
+ Licence for libxslt except libexslt
+ ----------------------------------------------------------------------
+ Copyright (C) 2001-2002 Daniel Veillard. All Rights Reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is fur-
+ nished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+ NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ DANIEL VEILLARD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+ NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Except as contained in this notice, the name of Daniel Veillard shall not
+ be used in advertising or otherwise to promote the sale, use or other deal-
+ ings in this Software without prior written authorization from him.
+
+ ----------------------------------------------------------------------
+
+ Licence for libexslt
+ ----------------------------------------------------------------------
+ Copyright (C) 2001-2002 Thomas Broyer, Charlie Bozeman and Daniel Veillard.
+ All Rights Reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is fur-
+ nished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+ NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+ NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Except as contained in this notice, the name of the authors shall not
+ be used in advertising or otherwise to promote the sale, use or other deal-
+ ings in this Software without prior written authorization from him.
+ ----------------------------------------------------------------------
+
### zlib
@@ -1103,15 +396,15 @@ zlib license
http://www.zlib.net/zlib_license.html
Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
-
+
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
-
+
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
-
+
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
@@ -1119,10 +412,10 @@ http://www.zlib.net/zlib_license.html
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
-
+
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
-
+
### libiconv
@@ -1130,41 +423,41 @@ LGPL
https://www.gnu.org/software/libiconv/
- GNU LIBRARY GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
Copyright (C) 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
-
+
[This is the first released version of the library GPL. It is
numbered 2 because it goes with version 2 of the ordinary GPL.]
-
- Preamble
-
+
+ Preamble
+
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
-
+
This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any
other libraries whose authors decide to use it. You can use it for
your libraries, too.
-
+
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
-
+
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if
you distribute copies of the library, or if you modify it.
-
+
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
@@ -1172,11 +465,11 @@ https://www.gnu.org/software/libiconv/
complete object files to the recipients so that they can relink them
with the library, after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
-
+
Our method of protecting your rights has two steps: (1) copyright
the library, and (2) offer you this license which gives you legal
permission to copy, distribute and/or modify the library.
-
+
Also, for each distributor's protection, we want to make certain
that everyone understands that there is no warranty for this free
library. If the library is modified by someone else and passed on, we
@@ -1190,14 +483,14 @@ https://www.gnu.org/software/libiconv/
transforming the program into proprietary software. To prevent this,
we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
-
+
Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License, which was designed for utility programs. This
license, the GNU Library General Public License, applies to certain
designated libraries. This license is quite different from the ordinary
one; be sure to read it in full, and don't assume that anything in it is
the same as in the ordinary license.
-
+
The reason we have a separate public license for some libraries is that
they blur the distinction we usually make between modifying or adding to a
program and simply using it. Linking a program with a library, without
@@ -1206,12 +499,12 @@ https://www.gnu.org/software/libiconv/
a textual and legal sense, the linked executable is a combined work, a
derivative of the original library, and the ordinary General Public License
treats it as such.
-
+
Because of this blurred distinction, using the ordinary General
Public License for libraries did not effectively promote software
sharing, because most developers did not use the libraries. We
concluded that weaker conditions might promote sharing better.
-
+
However, unrestricted linking of non-free programs would deprive the
users of those programs of all benefit from the free status of the
libraries themselves. This Library General Public License is intended to
@@ -1221,29 +514,29 @@ https://www.gnu.org/software/libiconv/
this as regards changes in header files, but we have achieved it as regards
changes in the actual functions of the Library.) The hope is that this
will lead to faster development of free libraries.
-
+
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, while the latter only
works together with the library.
-
+
Note that it is possible for a library to be covered by the ordinary
General Public License rather than by this special one.
- GNU LIBRARY GENERAL PUBLIC LICENSE
+ GNU LIBRARY GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
+
0. This License Agreement applies to any software library which
contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Library
General Public License (also called "this License"). Each licensee is
addressed as "you".
-
+
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
-
+
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
@@ -1251,13 +544,13 @@ https://www.gnu.org/software/libiconv/
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
-
+
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
-
+
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
@@ -1265,7 +558,7 @@ https://www.gnu.org/software/libiconv/
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
-
+
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
@@ -1273,7 +566,7 @@ https://www.gnu.org/software/libiconv/
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
-
+
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
@@ -1282,15 +575,15 @@ https://www.gnu.org/software/libiconv/
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
-
+
a) The modified work must itself be a software library.
-
+
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
-
+
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
-
+
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
@@ -1298,14 +591,14 @@ https://www.gnu.org/software/libiconv/
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
-
+
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
-
+
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
@@ -1316,17 +609,17 @@ https://www.gnu.org/software/libiconv/
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
-
+
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
-
+
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
-
+
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
@@ -1339,49 +632,49 @@ https://www.gnu.org/software/libiconv/
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
-
+
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
-
+
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
-
+
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
-
+
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
-
+
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
-
+
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
-
+
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
-
+
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
@@ -1393,7 +686,7 @@ https://www.gnu.org/software/libiconv/
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
-
+
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
@@ -1401,7 +694,7 @@ https://www.gnu.org/software/libiconv/
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
-
+
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
@@ -1413,19 +706,19 @@ https://www.gnu.org/software/libiconv/
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
-
+
b) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
-
+
c) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
-
+
d) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
-
+
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
@@ -1434,7 +727,7 @@ https://www.gnu.org/software/libiconv/
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
-
+
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
@@ -1447,16 +740,16 @@ https://www.gnu.org/software/libiconv/
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
-
+
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
-
+
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
-
+
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
@@ -1464,7 +757,7 @@ https://www.gnu.org/software/libiconv/
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
-
+
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
@@ -1473,7 +766,7 @@ https://www.gnu.org/software/libiconv/
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
-
+
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
@@ -1494,11 +787,11 @@ https://www.gnu.org/software/libiconv/
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
-
+
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
-
+
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
@@ -1509,10 +802,10 @@ https://www.gnu.org/software/libiconv/
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
-
+
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
-
+
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
@@ -1520,12 +813,12 @@ https://www.gnu.org/software/libiconv/
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
-
+
13. The Free Software Foundation may publish revised and/or new
versions of the Library General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
-
+
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
@@ -1542,9 +835,9 @@ https://www.gnu.org/software/libiconv/
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
-
- NO WARRANTY
-
+
+ NO WARRANTY
+
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
@@ -1554,7 +847,7 @@ https://www.gnu.org/software/libiconv/
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
+
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
@@ -1565,50 +858,1367 @@ https://www.gnu.org/software/libiconv/
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- Appendix: How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
- possible use to the public, we recommend making it free software that
- everyone can redistribute and change. You can do so by permitting
- redistribution under these terms (or, alternatively, under the terms of the
- ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
- safest to attach them to the start of each source file to most effectively
- convey the exclusion of warranty; and each file should have at least the
- "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- MA 02110-1301, USA
-
- Also add information on how to contact you by electronic and paper mail.
-
- You should also get your employer (if you work as a programmer) or your
- school, if any, to sign a "copyright disclaimer" for the library, if
- necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- , 1 April 1990
- Ty Coon, President of Vice
-
- That's all there is to it!
+
+ END OF TERMS AND CONDITIONS
+
+
+### isorelax:isorelax
+
+MIT
+
+http://iso-relax.sourceforge.net/
+
+ Copyright (c) 2001-2002, SourceForge ISO-RELAX Project (ASAMI
+ Tomoharu, Daisuke Okajima, Kohsuke Kawaguchi, and MURATA Makoto)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+### net.sf.saxon:Saxon-HE
+
+MPL 2.0
+
+http://www.saxonica.com/
+
+ Mozilla Public License Version 2.0
+ ==================================
+
+ 1. Definitions
+ --------------
+
+ 1.1. "Contributor"
+ means each individual or legal entity that creates, contributes to
+ the creation of, or owns Covered Software.
+
+ 1.2. "Contributor Version"
+ means the combination of the Contributions of others (if any) used
+ by a Contributor and that particular Contributor's Contribution.
+
+ 1.3. "Contribution"
+ means Covered Software of a particular Contributor.
+
+ 1.4. "Covered Software"
+ means Source Code Form to which the initial Contributor has attached
+ the notice in Exhibit A, the Executable Form of such Source Code
+ Form, and Modifications of such Source Code Form, in each case
+ including portions thereof.
+
+ 1.5. "Incompatible With Secondary Licenses"
+ means
+
+ (a) that the initial Contributor has attached the notice described
+ in Exhibit B to the Covered Software; or
+
+ (b) that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the
+ terms of a Secondary License.
+
+ 1.6. "Executable Form"
+ means any form of the work other than Source Code Form.
+
+ 1.7. "Larger Work"
+ means a work that combines Covered Software with other material, in
+ a separate file or files, that is not Covered Software.
+
+ 1.8. "License"
+ means this document.
+
+ 1.9. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any and
+ all of the rights conveyed by this License.
+
+ 1.10. "Modifications"
+ means any of the following:
+
+ (a) any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered
+ Software; or
+
+ (b) any new file in Source Code Form that contains any Covered
+ Software.
+
+ 1.11. "Patent Claims" of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale, having
+ made, import, or transfer of either its Contributions or its
+ Contributor Version.
+
+ 1.12. "Secondary License"
+ means either the GNU General Public License, Version 2.0, the GNU
+ Lesser General Public License, Version 2.1, the GNU Affero General
+ Public License, Version 3.0, or any later versions of those
+ licenses.
+
+ 1.13. "Source Code Form"
+ means the form of the work preferred for making modifications.
+
+ 1.14. "You" (or "Your")
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+ 2. License Grants and Conditions
+ --------------------------------
+
+ 2.1. Grants
+
+ Each Contributor hereby grants You a world-wide, royalty-free,
+ non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+
+ (b) under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+ 2.2. Effective Date
+
+ The licenses granted in Section 2.1 with respect to any Contribution
+ become effective for each Contribution on the date the Contributor first
+ distributes such Contribution.
+
+ 2.3. Limitations on Grant Scope
+
+ The licenses granted in this Section 2 are the only rights granted under
+ this License. No additional rights or licenses will be implied from the
+ distribution or licensing of Covered Software under this License.
+ Notwithstanding Section 2.1(b) above, no patent license is granted by a
+ Contributor:
+
+ (a) for any code that a Contributor has removed from Covered Software;
+ or
+
+ (b) for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+ (c) under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+ This License does not grant any rights in the trademarks, service marks,
+ or logos of any Contributor (except as may be necessary to comply with
+ the notice requirements in Section 3.4).
+
+ 2.4. Subsequent Licenses
+
+ No Contributor makes additional grants as a result of Your choice to
+ distribute the Covered Software under a subsequent version of this
+ License (see Section 10.2) or under the terms of a Secondary License (if
+ permitted under the terms of Section 3.3).
+
+ 2.5. Representation
+
+ Each Contributor represents that the Contributor believes its
+ Contributions are its original creation(s) or it has sufficient rights
+ to grant the rights to its Contributions conveyed by this License.
+
+ 2.6. Fair Use
+
+ This License is not intended to limit any rights You have under
+ applicable copyright doctrines of fair use, fair dealing, or other
+ equivalents.
+
+ 2.7. Conditions
+
+ Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+ in Section 2.1.
+
+ 3. Responsibilities
+ -------------------
+
+ 3.1. Distribution of Source Form
+
+ All distribution of Covered Software in Source Code Form, including any
+ Modifications that You create or to which You contribute, must be under
+ the terms of this License. You must inform recipients that the Source
+ Code Form of the Covered Software is governed by the terms of this
+ License, and how they can obtain a copy of this License. You may not
+ attempt to alter or restrict the recipients' rights in the Source Code
+ Form.
+
+ 3.2. Distribution of Executable Form
+
+ If You distribute Covered Software in Executable Form then:
+
+ (a) such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients of
+ the Executable Form how they can obtain a copy of such Source Code
+ Form by reasonable means in a timely manner, at a charge no more
+ than the cost of distribution to the recipient; and
+
+ (b) You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients' rights in the Source Code Form under this License.
+
+ 3.3. Distribution of a Larger Work
+
+ You may create and distribute a Larger Work under terms of Your choice,
+ provided that You also comply with the requirements of this License for
+ the Covered Software. If the Larger Work is a combination of Covered
+ Software with a work governed by one or more Secondary Licenses, and the
+ Covered Software is not Incompatible With Secondary Licenses, this
+ License permits You to additionally distribute such Covered Software
+ under the terms of such Secondary License(s), so that the recipient of
+ the Larger Work may, at their option, further distribute the Covered
+ Software under the terms of either this License or such Secondary
+ License(s).
+
+ 3.4. Notices
+
+ You may not remove or alter the substance of any license notices
+ (including copyright notices, patent notices, disclaimers of warranty,
+ or limitations of liability) contained within the Source Code Form of
+ the Covered Software, except that You may alter any license notices to
+ the extent required to remedy known factual inaccuracies.
+
+ 3.5. Application of Additional Terms
+
+ You may choose to offer, and to charge a fee for, warranty, support,
+ indemnity or liability obligations to one or more recipients of Covered
+ Software. However, You may do so only on Your own behalf, and not on
+ behalf of any Contributor. You must make it absolutely clear that any
+ such warranty, support, indemnity, or liability obligation is offered by
+ You alone, and You hereby agree to indemnify every Contributor for any
+ liability incurred by such Contributor as a result of warranty, support,
+ indemnity or liability terms You offer. You may include additional
+ disclaimers of warranty and limitations of liability specific to any
+ jurisdiction.
+
+ 4. Inability to Comply Due to Statute or Regulation
+ ---------------------------------------------------
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Software due to
+ statute, judicial order, or regulation then You must: (a) comply with
+ the terms of this License to the maximum extent possible; and (b)
+ describe the limitations and the code they affect. Such description must
+ be placed in a text file included with all distributions of the Covered
+ Software under this License. Except to the extent prohibited by statute
+ or regulation, such description must be sufficiently detailed for a
+ recipient of ordinary skill to be able to understand it.
+
+ 5. Termination
+ --------------
+
+ 5.1. The rights granted under this License will terminate automatically
+ if You fail to comply with any of its terms. However, if You become
+ compliant, then the rights granted under this License from a particular
+ Contributor are reinstated (a) provisionally, unless and until such
+ Contributor explicitly and finally terminates Your grants, and (b) on an
+ ongoing basis, if such Contributor fails to notify You of the
+ non-compliance by some reasonable means prior to 60 days after You have
+ come back into compliance. Moreover, Your grants from a particular
+ Contributor are reinstated on an ongoing basis if such Contributor
+ notifies You of the non-compliance by some reasonable means, this is the
+ first time You have received notice of non-compliance with this License
+ from such Contributor, and You become compliant prior to 30 days after
+ Your receipt of the notice.
+
+ 5.2. If You initiate litigation against any entity by asserting a patent
+ infringement claim (excluding declaratory judgment actions,
+ counter-claims, and cross-claims) alleging that a Contributor Version
+ directly or indirectly infringes any patent, then the rights granted to
+ You by any and all Contributors for the Covered Software under Section
+ 2.1 of this License shall terminate.
+
+ 5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+ end user license agreements (excluding distributors and resellers) which
+ have been validly granted by You or Your distributors under this License
+ prior to termination shall survive termination.
+
+ ************************************************************************
+ * *
+ * 6. Disclaimer of Warranty *
+ * ------------------------- *
+ * *
+ * Covered Software is provided under this License on an "as is" *
+ * basis, without warranty of any kind, either expressed, implied, or *
+ * statutory, including, without limitation, warranties that the *
+ * Covered Software is free of defects, merchantable, fit for a *
+ * particular purpose or non-infringing. The entire risk as to the *
+ * quality and performance of the Covered Software is with You. *
+ * Should any Covered Software prove defective in any respect, You *
+ * (not any Contributor) assume the cost of any necessary servicing, *
+ * repair, or correction. This disclaimer of warranty constitutes an *
+ * essential part of this License. No use of any Covered Software is *
+ * authorized under this License except under this disclaimer. *
+ * *
+ ************************************************************************
+
+ ************************************************************************
+ * *
+ * 7. Limitation of Liability *
+ * -------------------------- *
+ * *
+ * Under no circumstances and under no legal theory, whether tort *
+ * (including negligence), contract, or otherwise, shall any *
+ * Contributor, or anyone who distributes Covered Software as *
+ * permitted above, be liable to You for any direct, indirect, *
+ * special, incidental, or consequential damages of any character *
+ * including, without limitation, damages for lost profits, loss of *
+ * goodwill, work stoppage, computer failure or malfunction, or any *
+ * and all other commercial damages or losses, even if such party *
+ * shall have been informed of the possibility of such damages. This *
+ * limitation of liability shall not apply to liability for death or *
+ * personal injury resulting from such party's negligence to the *
+ * extent applicable law prohibits such limitation. Some *
+ * jurisdictions do not allow the exclusion or limitation of *
+ * incidental or consequential damages, so this exclusion and *
+ * limitation may not apply to You. *
+ * *
+ ************************************************************************
+
+ 8. Litigation
+ -------------
+
+ Any litigation relating to this License may be brought only in the
+ courts of a jurisdiction where the defendant maintains its principal
+ place of business and such litigation shall be governed by laws of that
+ jurisdiction, without reference to its conflict-of-law provisions.
+ Nothing in this Section shall prevent a party's ability to bring
+ cross-claims or counter-claims.
+
+ 9. Miscellaneous
+ ----------------
+
+ This License represents the complete agreement concerning the subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. Any law or regulation which provides
+ that the language of a contract shall be construed against the drafter
+ shall not be used to construe this License against a Contributor.
+
+ 10. Versions of the License
+ ---------------------------
+
+ 10.1. New Versions
+
+ Mozilla Foundation is the license steward. Except as provided in Section
+ 10.3, no one other than the license steward has the right to modify or
+ publish new versions of this License. Each version will be given a
+ distinguishing version number.
+
+ 10.2. Effect of New Versions
+
+ You may distribute the Covered Software under the terms of the version
+ of the License under which You originally received the Covered Software,
+ or under the terms of any subsequent version published by the license
+ steward.
+
+ 10.3. Modified Versions
+
+ If you create software not governed by this License, and you want to
+ create a new license for such software, you may create and use a
+ modified version of this License if you rename the license and remove
+ any references to the name of the license steward (except to note that
+ such modified license differs from this License).
+
+ 10.4. Distributing Source Code Form that is Incompatible With Secondary
+ Licenses
+
+ If You choose to distribute Source Code Form that is Incompatible With
+ Secondary Licenses under the terms of this version of the License, the
+ notice described in Exhibit B of this License must be attached.
+
+
+### net.sourceforge.htmlunit:neko-htmlunit
+
+Apache 2.0
+
+https://github.com/HtmlUnit/htmlunit-neko
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+
+### nu.validator:jing
+
+BSD-3-Clause
+
+http://www.thaiopensource.com/relaxng/jing.html
+
+ Copyright (c) 2001-2003 Thai Open Source Software Center Ltd
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+ * Neither the name of the Thai Open Source Software Center Ltd nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+
+### org.nokogiri:nekodtd
+
+Apache 2.0
+
+https://github.com/sparklemotion/nekodtd
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+
+### xalan:serializer and xalan:xalan
+
+Apache 2.0
+
+https://xml.apache.org/xalan-j/
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+
+### xerces:xercesImpl
+
+Apache 2.0
+
+https://xerces.apache.org/xerces2-j/
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+
+### xml-apis:xml-apis
+
+Apache 2.0
+
+https://xerces.apache.org/xml-commons/
+
+ Unless otherwise noted all files in XML Commons are covered under the
+ Apache License Version 2.0. Please read the LICENSE and NOTICE files.
+
+ XML Commons contains some software and documentation that is covered
+ under a number of different licenses. This applies particularly to the
+ xml-commons/java/external/ directory. Most files under
+ xml-commons/java/external/ are covered under their respective
+ LICENSE.*.txt files; see the matching README.*.txt files for
+ descriptions.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/LICENSE.md b/LICENSE.md
index 1632aee7af..b649dd875d 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
The MIT License
-Copyright 2008 -- 2018 by Aaron Patterson, Mike Dalessio, Charles Nutter, Sergio Arbeo, Patrick Mahoney, Yoko Harada, Akinori MUSHA, John Shahid, Lars Kanis
+Copyright 2008 -- 2023 by Mike Dalessio, Aaron Patterson, Yoko Harada, Akinori MUSHA, John Shahid, Karol Bucek, Sam Ruby, Craig Barnes, Stephen Checkoway, Lars Kanis, Sergio Arbeo, Timothy Elliott, Nobuyoshi Nakada, Charles Nutter, Patrick Mahoney.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
diff --git a/Manifest.txt b/Manifest.txt
deleted file mode 100644
index bb1360f924..0000000000
--- a/Manifest.txt
+++ /dev/null
@@ -1,239 +0,0 @@
-LICENSE-DEPENDENCIES.md
-LICENSE.md
-README.md
-bin/nokogiri
-dependencies.yml
-ext/java/nokogiri/EncodingHandler.java
-ext/java/nokogiri/HtmlDocument.java
-ext/java/nokogiri/HtmlElementDescription.java
-ext/java/nokogiri/HtmlEntityLookup.java
-ext/java/nokogiri/HtmlSaxParserContext.java
-ext/java/nokogiri/HtmlSaxPushParser.java
-ext/java/nokogiri/NokogiriService.java
-ext/java/nokogiri/XmlAttr.java
-ext/java/nokogiri/XmlAttributeDecl.java
-ext/java/nokogiri/XmlCdata.java
-ext/java/nokogiri/XmlComment.java
-ext/java/nokogiri/XmlDocument.java
-ext/java/nokogiri/XmlDocumentFragment.java
-ext/java/nokogiri/XmlDtd.java
-ext/java/nokogiri/XmlElement.java
-ext/java/nokogiri/XmlElementContent.java
-ext/java/nokogiri/XmlElementDecl.java
-ext/java/nokogiri/XmlEntityDecl.java
-ext/java/nokogiri/XmlEntityReference.java
-ext/java/nokogiri/XmlNamespace.java
-ext/java/nokogiri/XmlNode.java
-ext/java/nokogiri/XmlNodeSet.java
-ext/java/nokogiri/XmlProcessingInstruction.java
-ext/java/nokogiri/XmlReader.java
-ext/java/nokogiri/XmlRelaxng.java
-ext/java/nokogiri/XmlSaxParserContext.java
-ext/java/nokogiri/XmlSaxPushParser.java
-ext/java/nokogiri/XmlSchema.java
-ext/java/nokogiri/XmlSyntaxError.java
-ext/java/nokogiri/XmlText.java
-ext/java/nokogiri/XmlXpathContext.java
-ext/java/nokogiri/XsltStylesheet.java
-ext/java/nokogiri/internals/ClosedStreamException.java
-ext/java/nokogiri/internals/HtmlDomParserContext.java
-ext/java/nokogiri/internals/IgnoreSchemaErrorsErrorHandler.java
-ext/java/nokogiri/internals/NokogiriBlockingQueueInputStream.java
-ext/java/nokogiri/internals/NokogiriDomParser.java
-ext/java/nokogiri/internals/NokogiriEncodingReaderWrapper.java
-ext/java/nokogiri/internals/NokogiriEntityResolver.java
-ext/java/nokogiri/internals/NokogiriErrorHandler.java
-ext/java/nokogiri/internals/NokogiriHandler.java
-ext/java/nokogiri/internals/NokogiriHelpers.java
-ext/java/nokogiri/internals/NokogiriNamespaceCache.java
-ext/java/nokogiri/internals/NokogiriNamespaceContext.java
-ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java
-ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java
-ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java
-ext/java/nokogiri/internals/NokogiriXPathFunction.java
-ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java
-ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java
-ext/java/nokogiri/internals/NokogiriXsltErrorListener.java
-ext/java/nokogiri/internals/ParserContext.java
-ext/java/nokogiri/internals/ReaderNode.java
-ext/java/nokogiri/internals/SaveContextVisitor.java
-ext/java/nokogiri/internals/SchemaErrorHandler.java
-ext/java/nokogiri/internals/UncloseableInputStream.java
-ext/java/nokogiri/internals/XalanDTMManagerPatch.java
-ext/java/nokogiri/internals/XmlDeclHandler.java
-ext/java/nokogiri/internals/XmlDomParserContext.java
-ext/java/nokogiri/internals/XmlSaxParser.java
-ext/java/nokogiri/internals/c14n/AttrCompare.java
-ext/java/nokogiri/internals/c14n/C14nHelper.java
-ext/java/nokogiri/internals/c14n/CanonicalFilter.java
-ext/java/nokogiri/internals/c14n/CanonicalizationException.java
-ext/java/nokogiri/internals/c14n/Canonicalizer.java
-ext/java/nokogiri/internals/c14n/Canonicalizer11.java
-ext/java/nokogiri/internals/c14n/Canonicalizer11_OmitComments.java
-ext/java/nokogiri/internals/c14n/Canonicalizer11_WithComments.java
-ext/java/nokogiri/internals/c14n/Canonicalizer20010315.java
-ext/java/nokogiri/internals/c14n/Canonicalizer20010315Excl.java
-ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclOmitComments.java
-ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclWithComments.java
-ext/java/nokogiri/internals/c14n/Canonicalizer20010315OmitComments.java
-ext/java/nokogiri/internals/c14n/Canonicalizer20010315WithComments.java
-ext/java/nokogiri/internals/c14n/CanonicalizerBase.java
-ext/java/nokogiri/internals/c14n/CanonicalizerPhysical.java
-ext/java/nokogiri/internals/c14n/CanonicalizerSpi.java
-ext/java/nokogiri/internals/c14n/Constants.java
-ext/java/nokogiri/internals/c14n/ElementProxy.java
-ext/java/nokogiri/internals/c14n/HelperNodeList.java
-ext/java/nokogiri/internals/c14n/IgnoreAllErrorHandler.java
-ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java
-ext/java/nokogiri/internals/c14n/InvalidCanonicalizerException.java
-ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java
-ext/java/nokogiri/internals/c14n/NodeFilter.java
-ext/java/nokogiri/internals/c14n/UtfHelpper.java
-ext/java/nokogiri/internals/c14n/XMLUtils.java
-ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java
-ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java
-ext/nokogiri/depend
-ext/nokogiri/extconf.rb
-ext/nokogiri/html_document.c
-ext/nokogiri/html_document.h
-ext/nokogiri/html_element_description.c
-ext/nokogiri/html_element_description.h
-ext/nokogiri/html_entity_lookup.c
-ext/nokogiri/html_entity_lookup.h
-ext/nokogiri/html_sax_parser_context.c
-ext/nokogiri/html_sax_parser_context.h
-ext/nokogiri/html_sax_push_parser.c
-ext/nokogiri/html_sax_push_parser.h
-ext/nokogiri/nokogiri.c
-ext/nokogiri/nokogiri.h
-ext/nokogiri/xml_attr.c
-ext/nokogiri/xml_attr.h
-ext/nokogiri/xml_attribute_decl.c
-ext/nokogiri/xml_attribute_decl.h
-ext/nokogiri/xml_cdata.c
-ext/nokogiri/xml_cdata.h
-ext/nokogiri/xml_comment.c
-ext/nokogiri/xml_comment.h
-ext/nokogiri/xml_document.c
-ext/nokogiri/xml_document.h
-ext/nokogiri/xml_document_fragment.c
-ext/nokogiri/xml_document_fragment.h
-ext/nokogiri/xml_dtd.c
-ext/nokogiri/xml_dtd.h
-ext/nokogiri/xml_element_content.c
-ext/nokogiri/xml_element_content.h
-ext/nokogiri/xml_element_decl.c
-ext/nokogiri/xml_element_decl.h
-ext/nokogiri/xml_encoding_handler.c
-ext/nokogiri/xml_encoding_handler.h
-ext/nokogiri/xml_entity_decl.c
-ext/nokogiri/xml_entity_decl.h
-ext/nokogiri/xml_entity_reference.c
-ext/nokogiri/xml_entity_reference.h
-ext/nokogiri/xml_io.c
-ext/nokogiri/xml_io.h
-ext/nokogiri/xml_libxml2_hacks.c
-ext/nokogiri/xml_libxml2_hacks.h
-ext/nokogiri/xml_namespace.c
-ext/nokogiri/xml_namespace.h
-ext/nokogiri/xml_node.c
-ext/nokogiri/xml_node.h
-ext/nokogiri/xml_node_set.c
-ext/nokogiri/xml_node_set.h
-ext/nokogiri/xml_processing_instruction.c
-ext/nokogiri/xml_processing_instruction.h
-ext/nokogiri/xml_reader.c
-ext/nokogiri/xml_reader.h
-ext/nokogiri/xml_relax_ng.c
-ext/nokogiri/xml_relax_ng.h
-ext/nokogiri/xml_sax_parser.c
-ext/nokogiri/xml_sax_parser.h
-ext/nokogiri/xml_sax_parser_context.c
-ext/nokogiri/xml_sax_parser_context.h
-ext/nokogiri/xml_sax_push_parser.c
-ext/nokogiri/xml_sax_push_parser.h
-ext/nokogiri/xml_schema.c
-ext/nokogiri/xml_schema.h
-ext/nokogiri/xml_syntax_error.c
-ext/nokogiri/xml_syntax_error.h
-ext/nokogiri/xml_text.c
-ext/nokogiri/xml_text.h
-ext/nokogiri/xml_xpath_context.c
-ext/nokogiri/xml_xpath_context.h
-ext/nokogiri/xslt_stylesheet.c
-ext/nokogiri/xslt_stylesheet.h
-lib/isorelax.jar
-lib/jing.jar
-lib/nekodtd.jar
-lib/nekohtml.jar
-lib/nokogiri.rb
-lib/nokogiri/css.rb
-lib/nokogiri/css/node.rb
-lib/nokogiri/css/parser.rb
-lib/nokogiri/css/parser.y
-lib/nokogiri/css/parser_extras.rb
-lib/nokogiri/css/syntax_error.rb
-lib/nokogiri/css/tokenizer.rb
-lib/nokogiri/css/tokenizer.rex
-lib/nokogiri/css/xpath_visitor.rb
-lib/nokogiri/decorators/slop.rb
-lib/nokogiri/html.rb
-lib/nokogiri/html/builder.rb
-lib/nokogiri/html/document.rb
-lib/nokogiri/html/document_fragment.rb
-lib/nokogiri/html/element_description.rb
-lib/nokogiri/html/element_description_defaults.rb
-lib/nokogiri/html/entity_lookup.rb
-lib/nokogiri/html/sax/parser.rb
-lib/nokogiri/html/sax/parser_context.rb
-lib/nokogiri/html/sax/push_parser.rb
-lib/nokogiri/syntax_error.rb
-lib/nokogiri/version.rb
-lib/nokogiri/xml.rb
-lib/nokogiri/xml/attr.rb
-lib/nokogiri/xml/attribute_decl.rb
-lib/nokogiri/xml/builder.rb
-lib/nokogiri/xml/cdata.rb
-lib/nokogiri/xml/character_data.rb
-lib/nokogiri/xml/document.rb
-lib/nokogiri/xml/document_fragment.rb
-lib/nokogiri/xml/dtd.rb
-lib/nokogiri/xml/element_content.rb
-lib/nokogiri/xml/element_decl.rb
-lib/nokogiri/xml/entity_decl.rb
-lib/nokogiri/xml/entity_reference.rb
-lib/nokogiri/xml/namespace.rb
-lib/nokogiri/xml/node.rb
-lib/nokogiri/xml/node/save_options.rb
-lib/nokogiri/xml/node_set.rb
-lib/nokogiri/xml/notation.rb
-lib/nokogiri/xml/parse_options.rb
-lib/nokogiri/xml/pp.rb
-lib/nokogiri/xml/pp/character_data.rb
-lib/nokogiri/xml/pp/node.rb
-lib/nokogiri/xml/processing_instruction.rb
-lib/nokogiri/xml/reader.rb
-lib/nokogiri/xml/relax_ng.rb
-lib/nokogiri/xml/sax.rb
-lib/nokogiri/xml/sax/document.rb
-lib/nokogiri/xml/sax/parser.rb
-lib/nokogiri/xml/sax/parser_context.rb
-lib/nokogiri/xml/sax/push_parser.rb
-lib/nokogiri/xml/schema.rb
-lib/nokogiri/xml/searchable.rb
-lib/nokogiri/xml/syntax_error.rb
-lib/nokogiri/xml/text.rb
-lib/nokogiri/xml/xpath.rb
-lib/nokogiri/xml/xpath/syntax_error.rb
-lib/nokogiri/xml/xpath_context.rb
-lib/nokogiri/xslt.rb
-lib/nokogiri/xslt/stylesheet.rb
-lib/serializer.jar
-lib/xalan.jar
-lib/xercesImpl.jar
-lib/xml-apis.jar
-lib/xsd/xmlparser/nokogiri.rb
-patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch
-patches/libxml2/0002-Remove-script-macro-support.patch
-patches/libxml2/0003-Update-entities-to-remove-handling-of-ssi.patch
-patches/libxslt/0001-Fix-security-framework-bypass.patch
diff --git a/README.md b/README.md
index 89d818f858..fc21be46bb 100644
--- a/README.md
+++ b/README.md
@@ -1,105 +1,168 @@
+
+
# Nokogiri
-## Description
+Nokogiri (鋸) makes it easy and painless to work with XML and HTML from Ruby. It provides a sensible, easy-to-understand API for [reading](https://nokogiri.org/tutorials/parsing_an_html_xml_document.html), writing, [modifying](https://nokogiri.org/tutorials/modifying_an_html_xml_document.html), and [querying](https://nokogiri.org/tutorials/searching_a_xml_html_document.html) documents. It is fast and standards-compliant by relying on native parsers like libxml2, libgumbo, and xerces.
+
+## Guiding Principles
+
+Some guiding principles Nokogiri tries to follow:
-Nokogiri (鋸) is an HTML, XML, SAX, and Reader parser. Among
-Nokogiri's many features is the ability to search documents via XPath
-or CSS3 selectors.
+- be secure-by-default by treating all documents as **untrusted** by default
+- be a **thin-as-reasonable layer** on top of the underlying parsers, and don't attempt to fix behavioral differences between the parsers
-## Links
+## Features Overview
-* https://nokogiri.org
-* [Installation Help](https://nokogiri.org/tutorials/installing_nokogiri.html)
-* [Tutorials](https://nokogiri.org)
-* [Cheat Sheet](https://github.com/sparklemotion/nokogiri/wiki/Cheat-sheet)
-* [GitHub](https://github.com/sparklemotion/nokogiri)
-* [Mailing List](https://groups.google.com/group/nokogiri-talk)
-* [Chat/Gitter](https://gitter.im/sparklemotion/nokogiri)
+- DOM Parser for XML, HTML4, and HTML5
+- SAX Parser for XML and HTML4
+- Push Parser for XML and HTML4
+- Document search via XPath 1.0
+- Document search via CSS3 selectors, with some jquery-like extensions
+- XSD Schema validation
+- XSLT transformation
+- "Builder" DSL for XML and HTML documents
## Status
-[](https://ci.nokogiri.org/teams/nokogiri-core/pipelines/nokogiri)
-[](https://ci.appveyor.com/project/flavorjones/nokogiri/branch/master)
-[](https://codeclimate.com/github/sparklemotion/nokogiri)
-[](https://codeclimate.com/github/sparklemotion/nokogiri/test_coverage)
+[](https://github.com/sparklemotion/nokogiri/actions/workflows/ci.yml)
+[](https://ci.appveyor.com/project/flavorjones/nokogiri/branch/main)
[](https://rubygems.org/gems/nokogiri)
-[](https://dependabot.com/compatibility-score.html?dependency-name=nokogiri&package-manager=bundler&version-scheme=semver)
-[](https://tidelift.com/subscription/pkg/rubygems-nokogiri?utm_source=rubygems-nokogiri&utm_medium=referral&utm_campaign=readme)
+[](https://docs.github.com/en/code-security/supply-chain-security/managing-vulnerabilities-in-your-projects-dependencies/about-dependabot-security-updates#about-compatibility-scores)
+[](https://bestpractices.coreinfrastructure.org/projects/5344)
+[](https://tidelift.com/subscription/pkg/rubygems-nokogiri?utm_source=rubygems-nokogiri&utm_medium=referral&utm_campaign=readme)
-## Features
-* XML/HTML DOM parser which handles broken HTML
-* XML/HTML SAX parser
-* XML/HTML Push parser
-* XPath 1.0 support for document searching
-* CSS3 selector support for document searching
-* XML/HTML builder
-* XSLT transformer
+## Support, Getting Help, and Reporting Issues
-Nokogiri parses and searches XML/HTML using native libraries (either C
-or Java, depending on your Ruby), which means it's fast and
-standards-compliant.
+All official documentation is posted at https://nokogiri.org (the source for which is at https://github.com/sparklemotion/nokogiri.org/, and we welcome contributions).
+### Reading
-## Installation
+Your first stops for learning more about Nokogiri should be:
-If this doesn't work:
+- [API Documentation](https://nokogiri.org/rdoc/index.html)
+- [Tutorials](https://nokogiri.org/tutorials/toc.html)
+- An excellent community-maintained [Cheat Sheet](https://github.com/sparklemotion/nokogiri/wiki/Cheat-sheet)
-```
-gem install nokogiri
-```
-then please start troubleshooting here:
+### Ask For Help
-> https://nokogiri.org/tutorials/installing_nokogiri.html
+There are a few ways to ask exploratory questions:
-There are currently 1,237 Stack Overflow questions about Nokogiri
-installation. The vast majority of them are out of date and therefore
-incorrect. __Please do not use Stack Overflow.__
+- The Nokogiri mailing list is active at https://groups.google.com/group/nokogiri-talk
+- Open an issue using the "Help Request" template at https://github.com/sparklemotion/nokogiri/issues
-Instead, [tell us](https://nokogiri.org/tutorials/getting_help.html)
-when the above instructions don't work for you. This allows us to both
-help you directly and improve the documentation.
+Please do not mail the maintainers at their personal addresses.
-### Binary packages
+### Report A Bug
-Binary packages are available for some distributions.
+The Nokogiri bug tracker is at https://github.com/sparklemotion/nokogiri/issues
-* Debian: https://packages.debian.org/sid/ruby-nokogiri
-* SuSE: https://download.opensuse.org/repositories/devel:/languages:/ruby:/extensions/
-* Fedora: http://s390.koji.fedoraproject.org/koji/packageinfo?packageID=6756
+Please use the "Bug Report" or "Installation Difficulties" templates.
-## Support
+### Security and Vulnerability Reporting
-All official documentation is posted at https://nokogiri.org (the source for which is at https://github.com/sparklemotion/nokogiri.org/, and we welcome contributions).
+Please report vulnerabilities at https://hackerone.com/nokogiri
-* The Nokogiri mailing list is active: https://groups.google.com/group/nokogiri-talk
-* The Nokogiri bug tracker is here: https://github.com/sparklemotion/nokogiri/issues
-* Before filing a bug report, please read our submission guidelines: http://nokogiri.org/tutorials/getting_help.html
-* The IRC channel is `#nokogiri` on freenode.
-* The project's GitHub wiki has an excellent community-maintained [Cheat Sheet](https://github.com/sparklemotion/nokogiri/wiki/Cheat-sheet) which might be useful.
+Full information and description of our security policy is in [`SECURITY.md`](SECURITY.md)
-Consider subscribing to [Tidelift][tidelift] which provides license assurances and timely security notifications for your open source dependencies, including Nokogiri. [Tidelift][tidelift] subscriptions also help the Nokogiri maintainers fund our [automated testing](https://ci.nokogiri.org) which in turn allows us to ship releases, bugfixes, and security updates more often.
- [tidelift]: https://tidelift.com/subscription/pkg/rubygems-nokogiri?utm_source=rubygems-nokogiri&utm_medium=referral&utm_campaign=readme
+### Semantic Versioning Policy
+Nokogiri follows [Semantic Versioning](https://semver.org/) (since 2017 or so). [](https://docs.github.com/en/code-security/supply-chain-security/managing-vulnerabilities-in-your-projects-dependencies/about-dependabot-security-updates#about-compatibility-scores)
-## Security and Vulnerability Reporting
+We bump `Major.Minor.Patch` versions following this guidance:
-Please report vulnerabilities at https://hackerone.com/nokogiri
+`Major`: (we've never done this)
-Full information and description of our security policy is in [`SECURITY.md`](SECURITY.md)
+- Significant backwards-incompatible changes to the public API that would require rewriting existing application code.
+- Some examples of backwards-incompatible changes we might someday consider for a Major release are at [`ROADMAP.md`](ROADMAP.md).
+
+`Minor`:
+
+- Features and bugfixes.
+- Updating packaged libraries for non-security-related reasons.
+- Dropping support for EOLed Ruby versions. [Some folks find this objectionable](https://github.com/sparklemotion/nokogiri/issues/1568), but [SemVer says this is OK if the public API hasn't changed](https://semver.org/#what-should-i-do-if-i-update-my-own-dependencies-without-changing-the-public-api).
+- Backwards-incompatible changes to internal or private methods and constants. These are detailed in the "Changes" section of each changelog entry.
+
+`Patch`:
+
+- Bugfixes.
+- Security updates.
+- Updating packaged libraries for security-related reasons.
+
+
+### Sponsorship
+
+You can help sponsor the maintainers of this software through one of these organizations:
+
+- [github.com/sponsors/flavorjones](https://github.com/sponsors/flavorjones)
+- [opencollective.com/nokogiri](https://opencollective.com/nokogiri)
+- [tidelift.com/subscription/pkg/rubygems-nokogiri](https://tidelift.com/subscription/pkg/rubygems-nokogiri?utm_source=rubygems-nokogiri&utm_medium=referral&utm_campaign=readme)
+
+
+## Installation
+
+Requirements:
+
+- Ruby >= 2.7
+- JRuby >= 9.4.0.0
+
+
+### Native Gems: Faster, more reliable installation
+
+"Native gems" contain pre-compiled libraries for a specific machine architecture. On supported platforms, this removes the need for compiling the C extension and the packaged libraries, or for system dependencies to exist. This results in **much faster installation** and **more reliable installation**, which as you probably know are the biggest headaches for Nokogiri users.
+
+### Supported Platforms
+
+Nokogiri ships pre-compiled, "native" gems for the following platforms:
+
+- Linux:
+ - `x86-linux` and `x86_64-linux` (req: `glibc >= 2.17`)
+ - `aarch64-linux` and `arm-linux` (req: `glibc >= 2.29`)
+ - Note that musl platforms like Alpine **are** supported
+- Darwin/MacOS: `x86_64-darwin` and `arm64-darwin`
+- Windows: `x86-mingw32`, `x64-mingw32`, and `x64-mingw-ucrt`
+- Java: any platform running JRuby 9.4 or higher
+
+To determine whether your system supports one of these gems, look at the output of `bundle platform` or `ruby -e 'puts Gem::Platform.local.to_s'`.
+
+If you're on a supported platform, either `gem install` or `bundle install` should install a native gem without any additional action on your part. This installation should only take a few seconds, and your output should look something like:
+
+``` sh
+$ gem install nokogiri
+Fetching nokogiri-1.11.0-x86_64-linux.gem
+Successfully installed nokogiri-1.11.0-x86_64-linux
+1 gem installed
+```
+
+
+### Other Installation Options
+
+Because Nokogiri is a C extension, it requires that you have a C compiler toolchain, Ruby development header files, and some system dependencies installed.
+The following may work for you if you have an appropriately-configured system:
-## Synopsis
+``` bash
+gem install nokogiri
+```
+
+If you have any issues, please visit [Installing Nokogiri](https://nokogiri.org/tutorials/installing_nokogiri.html) for more complete instructions and troubleshooting.
+
+
+## How To Use Nokogiri
-Nokogiri is a large library, but here is example usage for parsing and examining a document:
+Nokogiri is a large library, and so it's challenging to briefly summarize it. We've tried to provide long, real-world examples at [Tutorials](https://nokogiri.org/tutorials/toc.html).
+
+### Parsing and Querying
+
+Here is example usage for parsing and querying a document:
```ruby
#! /usr/bin/env ruby
@@ -108,51 +171,26 @@ require 'nokogiri'
require 'open-uri'
# Fetch and parse HTML document
-doc = Nokogiri::HTML(open('https://nokogiri.org/tutorials/installing_nokogiri.html'))
+doc = Nokogiri::HTML(URI.open('https://nokogiri.org/tutorials/installing_nokogiri.html'))
-puts "### Search for nodes by css"
+# Search for nodes by css
doc.css('nav ul.menu li a', 'article h2').each do |link|
puts link.content
end
-puts "### Search for nodes by xpath"
+# Search for nodes by xpath
doc.xpath('//nav//ul//li/a', '//article//h2').each do |link|
puts link.content
end
-puts "### Or mix and match."
+# Or mix and match
doc.search('nav ul.menu li a', '//article//h2').each do |link|
puts link.content
end
```
-## Requirements
-
-* Ruby 2.3.0 or higher, including any development packages necessary
- to compile native extensions.
-
-* In Nokogiri 1.6.0 and later libxml2 and libxslt are bundled with the
- gem, but if you want to use the system versions:
-
- * First, check out [the long list](http://www.xmlsoft.org/news.html)
- of fixes and changes between releases before deciding to use any
- version older than is bundled with Nokogiri.
-
- * At install time, set the environment variable
- `NOKOGIRI_USE_SYSTEM_LIBRARIES` or else use the
- `--use-system-libraries` argument. (See
- https://nokogiri.org/tutorials/installing_nokogiri.html#install-with-system-libraries
- for specifics.)
-
- * libxml2 >=2.6.21 with iconv support
- (libxml2-dev/-devel is also required)
-
- * libxslt, built with and supported by the given libxml2
- (libxslt-dev/-devel is also required)
-
-
-## Encoding
+### Encoding
Strings are always stored as UTF-8 internally. Methods that return
text values will always return UTF-8 encoded strings. Methods that
@@ -178,12 +216,41 @@ explicitly setting the encoding to EUC-JP on the parser:
```
-## Development
+## Technical Overview
+
+### Guiding Principles
+
+As noted above, two guiding principles of the software are:
+
+- be secure-by-default by treating all documents as **untrusted** by default
+- be a **thin-as-reasonable layer** on top of the underlying parsers, and don't attempt to fix behavioral differences between the parsers
+
+Notably, despite all parsers being standards-compliant, there are behavioral inconsistencies between the parsers used in the CRuby and JRuby implementations, and Nokogiri does not and should not attempt to remove these inconsistencies. Instead, we surface these differences in the test suite when they are important/semantic; or we intentionally write tests to depend only on the important/semantic bits (omitting whitespace from regex matchers on results, for example).
-```bash
- bundle install
- bundle exec rake compile test
-```
+
+### CRuby
+
+The Ruby (a.k.a., CRuby, MRI, YARV) implementation is a C extension that depends on libxml2 and libxslt (which in turn depend on zlib and possibly libiconv).
+
+These dependencies are met by default by Nokogiri's packaged versions of the libxml2 and libxslt source code, but a configuration option `--use-system-libraries` is provided to allow specification of alternative library locations. See [Installing Nokogiri](https://nokogiri.org/tutorials/installing_nokogiri.html) for full documentation.
+
+We provide native gems by pre-compiling libxml2 and libxslt (and potentially zlib and libiconv) and packaging them into the gem file. In this case, no compilation is necessary at installation time, which leads to faster and more reliable installation.
+
+See [`LICENSE-DEPENDENCIES.md`](LICENSE-DEPENDENCIES.md) for more information on which dependencies are provided in which native and source gems.
+
+
+### JRuby
+
+The Java (a.k.a. JRuby) implementation is a Java extension that depends primarily on Xerces and NekoHTML for parsing, though additional dependencies are on `isorelax`, `nekodtd`, `jing`, `serializer`, `xalan-j`, and `xml-apis`.
+
+These dependencies are provided by pre-compiled jar files packaged in the `java` platform gem.
+
+See [`LICENSE-DEPENDENCIES.md`](LICENSE-DEPENDENCIES.md) for more information on which dependencies are provided in which native and source gems.
+
+
+## Contributing
+
+See [`CONTRIBUTING.md`](CONTRIBUTING.md) for an intro guide to developing Nokogiri.
## Code of Conduct
@@ -196,3 +263,25 @@ We've adopted the Contributor Covenant code of conduct, which you can read in fu
This project is licensed under the terms of the MIT license.
See this license at [`LICENSE.md`](LICENSE.md).
+
+
+### Dependencies
+
+Some additional libraries may be distributed with your version of Nokogiri. Please see [`LICENSE-DEPENDENCIES.md`](LICENSE-DEPENDENCIES.md) for a discussion of the variations as well as the licenses thereof.
+
+
+## Authors
+
+- Mike Dalessio
+- Aaron Patterson
+- Yoko Harada
+- Akinori MUSHA
+- John Shahid
+- Karol Bucek
+- Sam Ruby
+- Craig Barnes
+- Stephen Checkoway
+- Lars Kanis
+- Sergio Arbeo
+- Timothy Elliott
+- Nobuyoshi Nakada
diff --git a/ROADMAP.md b/ROADMAP.md
index 4fa34a02da..af307133d7 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -2,10 +2,10 @@
## overhaul serialize/pretty printing API
-* https://github.com/sparklemotion/nokogiri/issues/530
+* [#530](https://github.com/sparklemotion/nokogiri/issues/530)
XHTML formatting can't be turned off
-* https://github.com/sparklemotion/nokogiri/issues/415
+* [#415](https://github.com/sparklemotion/nokogiri/issues/415)
XML formatting should be no formatting
@@ -16,36 +16,36 @@
## Node should not be Enumerable; and should have a better attributes API
-* https://github.com/sparklemotion/nokogiri/issues/679
+* [#679](https://github.com/sparklemotion/nokogiri/issues/679)
Mixing in Enumerable has some unintended consequences; plus we want to improve the attributes API
* Some ideas for a better attributes API?
- * (closed) https://github.com/sparklemotion/nokogiri/issues/666
- * https://github.com/sparklemotion/nokogiri/issues/765
+ * (closed) [#666](https://github.com/sparklemotion/nokogiri/issues/666)
+ * [#765](https://github.com/sparklemotion/nokogiri/issues/765)
## improve CSS query parsing
-* https://github.com/sparklemotion/nokogiri/issues/528
+* [#528](https://github.com/sparklemotion/nokogiri/issues/528)
support `:not()` with a nontrivial argument, like `:not(div p.c)`
-* https://github.com/sparklemotion/nokogiri/issues/451
+* [#451](https://github.com/sparklemotion/nokogiri/issues/451)
chained :not pseudoselectors
* better jQuery selector and CSS pseudo-selector support:
- * https://github.com/sparklemotion/nokogiri/issues/621
- * https://github.com/sparklemotion/nokogiri/issues/342
- * https://github.com/sparklemotion/nokogiri/issues/628
- * https://github.com/sparklemotion/nokogiri/issues/652
- * https://github.com/sparklemotion/nokogiri/issues/688
+ * [#621](https://github.com/sparklemotion/nokogiri/issues/621)
+ * [#342](https://github.com/sparklemotion/nokogiri/issues/342)
+ * [#628](https://github.com/sparklemotion/nokogiri/issues/628)
+ * [#652](https://github.com/sparklemotion/nokogiri/issues/652)
+ * [#688](https://github.com/sparklemotion/nokogiri/issues/688)
-* https://github.com/sparklemotion/nokogiri/issues/394
+* [#394](https://github.com/sparklemotion/nokogiri/issues/394)
nth-of-type is wrong, and possibly other selectors as well
-* https://github.com/sparklemotion/nokogiri/issues/309
+* [#309](https://github.com/sparklemotion/nokogiri/issues/309)
incorrect query being executed
-* https://github.com/sparklemotion/nokogiri/issues/350
+* [#350](https://github.com/sparklemotion/nokogiri/issues/350)
:has is wrong?
@@ -53,24 +53,24 @@
* there are a few tickets about searches not working properly if you
use or do not use the context node as part of the search.
- - https://github.com/sparklemotion/nokogiri/issues/213
- - https://github.com/sparklemotion/nokogiri/issues/370
- - https://github.com/sparklemotion/nokogiri/issues/454
- - https://github.com/sparklemotion/nokogiri/issues/572
+ - [#213](https://github.com/sparklemotion/nokogiri/issues/213)
+ - [#370](https://github.com/sparklemotion/nokogiri/issues/370)
+ - [#454](https://github.com/sparklemotion/nokogiri/issues/454)
+ - [#572](https://github.com/sparklemotion/nokogiri/issues/572)
could we fix this by making DocumentFragment be a subclass of NodeSet?
## Better Syntax for custom XPath function handler
-* https://github.com/sparklemotion/nokogiri/pull/464
+* [PR#464](https://github.com/sparklemotion/nokogiri/issues/464)
## Better Syntax around Node#xpath and NodeSet#xpath
* look at those methods, and use of Node#extract_params in Node#{css,search}
- * we should standardize on a hash of options for these and other calls
+ * we should standardize on a hash of options for these and other calls
* what should NodeSet#xpath return?
- * https://github.com/sparklemotion/nokogiri/issues/656
+ * [#656](https://github.com/sparklemotion/nokogiri/issues/656)
## Encoding
@@ -105,7 +105,23 @@ proper convention.
`collect_namespaces` is returning a hash, which means it can't return
namespaces with the same prefix. See this issue for background:
-> https://github.com/sparklemotion/nokogiri/issues/885
+> [#885](https://github.com/sparklemotion/nokogiri/issues/885)
Do we care? This seems like a useless method, but then again I hate
XML, so what do I know?
+
+
+## Overhaul `ParseOptions`
+
+Currently we mirror libxml2's parse options, and then retrofit those options on top of Xerces-J for JRuby.
+
+* I'd like to identify which options work across both parsers,
+* And overhaul the parse methods so that these options are easier to use.
+
+By "easier to use" I mean:
+
+* it's unwieldy to create a block to set/unset parse options
+* it's unwieldy to create a constant like `MY_PARSE_OPTIONS = Nokogiri::XML::ParseOptions::STRICT | Nokogiri::XML::ParseOptions::RECOVER ...`
+* some options are named dangerously poorly, like `NOENT` which [does the opposite of what it says](https://github.com/sparklemotion/nokogiri/issues/1582#issuecomment-562180275)
+* semantically some options should be set/unset together, specifically "this is a trusted document" or "this is an untrusted document" should flip the senses of `NONET` and `NOENT` and `DTDLOAD` together.
+* we need the ability to invent new parse options, like the one suggested in [#1582](https://github.com/sparklemotion/nokogiri/issues/1582) that would allow local entities but not external entities.
diff --git a/Rakefile b/Rakefile
index 7526d4df7b..1638c8625a 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,336 +1,10 @@
-# -*- ruby -*-
-require 'rubygems'
-require 'shellwords'
+# frozen_string_literal: true
-gem 'hoe'
-require 'hoe'
-Hoe.plugin :debugging
-Hoe.plugin :git
-Hoe.plugin :gemspec
-Hoe.plugin :bundler
+#
+# Tasks are all loaded from `rakelib/*.rake`.
+# You may want to use `rake -T` to see what's available.
+#
+require "bundler"
+NOKOGIRI_SPEC = Bundler.load_gemspec("nokogiri.gemspec")
-GENERATED_PARSER = "lib/nokogiri/css/parser.rb"
-GENERATED_TOKENIZER = "lib/nokogiri/css/tokenizer.rb"
-
-def java?
- /java/ === RUBY_PLATFORM
-end
-
-ENV['LANG'] = "en_US.UTF-8" # UBUNTU 10.04, Y U NO DEFAULT TO UTF-8?
-
-CrossRuby = Struct.new(:version, :host) {
- def ver
- @ver ||= version[/\A[^-]+/]
- end
-
- def minor_ver
- @minor_ver ||= ver[/\A\d\.\d(?=\.)/]
- end
-
- def api_ver_suffix
- case minor_ver
- when nil
- raise "unsupported version: #{ver}"
- else
- minor_ver.delete('.') << '0'
- end
- end
-
- def platform
- @platform ||=
- case host
- when /\Ax86_64-/
- 'x64-mingw32'
- when /\Ai[3-6]86-/
- 'x86-mingw32'
- else
- raise "unsupported host: #{host}"
- end
- end
-
- def tool(name)
- (@binutils_prefix ||=
- case platform
- when 'x64-mingw32'
- 'x86_64-w64-mingw32-'
- when 'x86-mingw32'
- 'i686-w64-mingw32-'
- end) + name
- end
-
- def target
- case platform
- when 'x64-mingw32'
- 'pei-x86-64'
- when 'x86-mingw32'
- 'pei-i386'
- end
- end
-
- def libruby_dll
- case platform
- when 'x64-mingw32'
- "x64-msvcrt-ruby#{api_ver_suffix}.dll"
- when 'x86-mingw32'
- "msvcrt-ruby#{api_ver_suffix}.dll"
- end
- end
-
- def dlls
- [
- 'kernel32.dll',
- 'msvcrt.dll',
- 'ws2_32.dll',
- *(case
- when ver >= '2.0.0'
- 'user32.dll'
- end),
- libruby_dll
- ]
- end
-}
-
-CROSS_RUBIES = File.read('.cross_rubies').lines.flat_map { |line|
- case line
- when /\A([^#]+):([^#]+)/
- CrossRuby.new($1, $2)
- else
- []
- end
-}
-
-ENV['RUBY_CC_VERSION'] ||= CROSS_RUBIES.map(&:ver).uniq.join(":")
-
-HOE = Hoe.spec 'nokogiri' do
- developer 'Aaron Patterson', 'aaronp@rubyforge.org'
- developer 'Mike Dalessio', 'mike.dalessio@gmail.com'
- developer 'Yoko Harada', 'yokolet@gmail.com'
- developer 'Tim Elliott', 'tle@holymonkey.com'
- developer 'Akinori MUSHA', 'knu@idaemons.org'
- developer 'John Shahid', 'jvshahid@gmail.com'
- developer 'Lars Kanis', 'lars@greiz-reinsdorf.de'
-
- license "MIT"
-
- self.readme_file = "README.md"
- self.history_file = "CHANGELOG.md"
-
- self.extra_rdoc_files = FileList['ext/nokogiri/*.c']
-
- self.clean_globs += [
- 'nokogiri.gemspec',
- 'lib/nokogiri/nokogiri.{bundle,jar,rb,so}',
- 'lib/nokogiri/[0-9].[0-9]',
- 'concourse/images/*.generated'
- ]
- self.clean_globs += Dir.glob("ports/*").reject { |d| d =~ %r{/archives$} }
-
- unless java?
- self.extra_deps += [
- ["mini_portile2", "~> 2.4.0"], # keep version in sync with extconf.rb
- ]
- end
-
- self.extra_dev_deps += [
- ["concourse", "~> 0.24"],
- ["hoe-bundler", "~> 1.2"],
- ["hoe-debugging", "~> 2.0"],
- ["hoe-gemspec", "~> 1.0"],
- ["hoe-git", "~> 1.6"],
- ["minitest", "~> 5.8"],
- ["racc", "~> 1.4.14"],
- ["rake", "~> 12.0"],
- ["rake-compiler", "~> 1.0.3"],
- ["rake-compiler-dock", "~> 0.7.0"],
- ["rexical", "~> 1.0.5"],
- ["simplecov", "~> 0.16"],
- ]
-
- self.spec_extras = {
- :extensions => ["ext/nokogiri/extconf.rb"],
- :required_ruby_version => '>= 2.3.0'
- }
-
- self.testlib = :minitest
- self.test_prelude = 'require "helper"' # ensure simplecov gets loaded before anything else
-end
-
-# ----------------------------------------
-
-def add_file_to_gem relative_source_path
- dest_path = File.join(gem_build_path, relative_source_path)
- dest_dir = File.dirname(dest_path)
-
- mkdir_p dest_dir unless Dir.exist?(dest_dir)
- rm_f dest_path if File.exist?(dest_path)
- safe_ln relative_source_path, dest_path
-
- HOE.spec.files << relative_source_path
-end
-
-def gem_build_path
- File.join 'pkg', HOE.spec.full_name
-end
-
-if java?
- # TODO: clean this section up.
- require "rake/javaextensiontask"
- Rake::JavaExtensionTask.new("nokogiri", HOE.spec) do |ext|
- jruby_home = RbConfig::CONFIG['prefix']
- ext.ext_dir = 'ext/java'
- ext.lib_dir = 'lib/nokogiri'
- ext.source_version = '1.6'
- ext.target_version = '1.6'
- jars = ["#{jruby_home}/lib/jruby.jar"] + FileList['lib/*.jar']
- ext.classpath = jars.map { |x| File.expand_path x }.join ':'
- ext.debug = true if ENV['JAVA_DEBUG']
- end
-
- task gem_build_path => [:compile] do
- add_file_to_gem 'lib/nokogiri/nokogiri.jar'
- end
-else
- begin
- require 'rake/extensioncompiler'
- # Ensure mingw compiler is installed
- Rake::ExtensionCompiler.mingw_host
- mingw_available = true
- rescue
- mingw_available = false
- end
- require "rake/extensiontask"
-
- HOE.spec.files.reject! { |f| f =~ %r{\.(java|jar)$} }
-
- dependencies = YAML.load_file("dependencies.yml")
-
- task gem_build_path do
- %w[libxml2 libxslt].each do |lib|
- version = dependencies[lib]["version"]
- archive = File.join("ports", "archives", "#{lib}-#{version}.tar.gz")
- add_file_to_gem archive
- patchesdir = File.join("patches", lib)
- patches = `#{['git', 'ls-files', patchesdir].shelljoin}`.split("\n").grep(/\.patch\z/)
- patches.each { |patch|
- add_file_to_gem patch
- }
- (untracked = Dir[File.join(patchesdir, '*.patch')] - patches).empty? or
- at_exit {
- untracked.each { |patch|
- puts "** WARNING: untracked patch file not added to gem: #{patch}"
- }
- }
- end
- end
-
- Rake::ExtensionTask.new("nokogiri", HOE.spec) do |ext|
- ext.lib_dir = File.join(*['lib', 'nokogiri', ENV['FAT_DIR']].compact)
- ext.config_options << ENV['EXTOPTS']
- if mingw_available
- ext.cross_compile = true
- ext.cross_platform = CROSS_RUBIES.map(&:platform).uniq
- ext.cross_config_options << "--enable-cross-build"
- ext.cross_compiling do |spec|
- libs = dependencies.map { |name, dep| "#{name}-#{dep["version"]}" }.join(', ')
-
- spec.post_install_message = <<-EOS
-Nokogiri is built with the packaged libraries: #{libs}.
- EOS
- spec.files.reject! { |path| File.fnmatch?('ports/*', path) }
- end
- end
- end
-end
-
-# ----------------------------------------
-
-desc "Generate css/parser.rb and css/tokenizer.rex"
-task 'generate' => [GENERATED_PARSER, GENERATED_TOKENIZER]
-task 'gem:spec' => 'generate' if Rake::Task.task_defined?("gem:spec")
-[:compile, :check_manifest].each do |task_name|
- Rake::Task[task_name].prerequisites << GENERATED_PARSER
- Rake::Task[task_name].prerequisites << GENERATED_TOKENIZER
-end
-
-file GENERATED_PARSER => "lib/nokogiri/css/parser.y" do |t|
- sh "racc -l -o #{t.name} #{t.prerequisites.first}"
-end
-
-file GENERATED_TOKENIZER => "lib/nokogiri/css/tokenizer.rex" do |t|
- sh "rex --independent -o #{t.name} #{t.prerequisites.first}"
-end
-
-# ----------------------------------------
-
-desc "set environment variables to build and/or test with debug options"
-task :debug do
- ENV['NOKOGIRI_DEBUG'] = "true"
- ENV['CFLAGS'] ||= ""
- ENV['CFLAGS'] += " -DDEBUG"
-end
-
-task :java_debug do
- ENV['JRUBY_OPTS'] = "#{ENV['JRUBY_OPTS']} --debug --dev"
- ENV['JAVA_OPTS'] = '-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y' if ENV['JAVA_DEBUG']
-end
-Rake::Task[:test].prerequisites << :java_debug
-
-if Hoe.plugins.include?(:debugging)
- ['valgrind', 'valgrind:mem', 'valgrind:mem0'].each do |task_name|
- Rake::Task["test:#{task_name}"].prerequisites << :compile
- end
-end
-
-require 'concourse'
-Concourse.new("nokogiri", fly_target: "ci") do |c|
- c.add_pipeline "nokogiri", "nokogiri.yml"
- c.add_pipeline "nokogiri-pr", "nokogiri-pr.yml"
-end
-
-# ----------------------------------------
-
-def verify_dll(dll, cross_ruby)
- dll_imports = cross_ruby.dlls
- dump = `#{['env', 'LANG=C', cross_ruby.tool('objdump'), '-p', dll].shelljoin}`
- raise "unexpected file format for generated dll #{dll}" unless /file format #{Regexp.quote(cross_ruby.target)}\s/ === dump
- raise "export function Init_nokogiri not in dll #{dll}" unless /Table.*\sInit_nokogiri\s/mi === dump
-
- # Verify that the expected DLL dependencies match the actual dependencies
- # and that no further dependencies exist.
- dll_imports_is = dump.scan(/DLL Name: (.*)$/).map(&:first).map(&:downcase).uniq
- if dll_imports_is.sort != dll_imports.sort
- raise "unexpected dll imports #{dll_imports_is.inspect} in #{dll}"
- end
- puts "#{dll}: Looks good!"
-end
-
-task :cross do
- rake_compiler_config_path = File.expand_path("~/.rake-compiler/config.yml")
- unless File.exists? rake_compiler_config_path
- raise "rake-compiler has not installed any cross rubies. Use rake-compiler-dock or 'rake gem:windows' for building binary windows gems."
- end
-
- CROSS_RUBIES.each do |cross_ruby|
- task "tmp/#{cross_ruby.platform}/nokogiri/#{cross_ruby.ver}/nokogiri.so" do |t|
- # To reduce the gem file size strip mingw32 dlls before packaging
- sh [cross_ruby.tool('strip'), '-S', t.name].shelljoin
- verify_dll t.name, cross_ruby
- end
- end
-end
-
-desc "build a windows gem without all the ceremony"
-task "gem:windows" do
- require "rake_compiler_dock"
- RakeCompilerDock.sh "bundle && rake cross native gem MAKE='nice make -j`nproc`' RUBY_CC_VERSION=#{ENV['RUBY_CC_VERSION']}"
-end
-
-desc "build a jruby gem with docker"
-task "gem:jruby" do
- require "rake_compiler_dock"
- RakeCompilerDock.sh "bundle && rake java gem", rubyvm: 'jruby'
-end
-
-require_relative "tasks/docker"
-
-# vim: syntax=Ruby
+task default: [:rubocop, :gumbo, :compile, :test]
diff --git a/STANDARD_RESPONSES.md b/STANDARD_RESPONSES.md
deleted file mode 100644
index 2c8b0cea03..0000000000
--- a/STANDARD_RESPONSES.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# Standard Responses to Requests
-
-These responses are needed often enough that I figured, let's just
-check them in for future reference and use.
-
-
-# Not enough information to help
-
-Hello!
-
-Thanks for asking this question! However, without more information,
-Team Nokogiri cannot reproduce your issue, and so we cannot offer much
-help.
-
-Please provide us with:
-
-* A self-contained script (one that we can run without modification,
- and preferably without making external network connections).
-
-* Please note that you need to include the XML/HTML that you are
- operating on.
-
-* The output of `nokogiri -v`, which will provide details about your
- platform and versions of ruby, libxml2 and nokogiri.
-
-For more information about requesting help or reporting bugs, please
-take a look at http://bit.ly/nokohelp
-
-Thank you so much!
-
-
-# Not a bug
-
-Hello!
-
-Thanks for asking this question! Your request for assistance using
-Nokogiri will not go unanswered!
-
-However, Nokogiri's Github Issues is reserved for reporting bugs or
-submitting patches. If you ask your question on the mailing list, Team
-Nokogiri promises someone will provide you with an answer in a timely
-manner.
-
-If you'd like to read up on Team Nokogiri's rationale for this policy,
-please go to http://bit.ly/nokohelp.
-
-Thank you so much for understanding! And thank you for using Nokogiri.
diff --git a/Vagrantfile b/Vagrantfile
new file mode 100644
index 0000000000..87056691e3
--- /dev/null
+++ b/Vagrantfile
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+Box = Struct.new(:shortname, :name, :provision)
+
+# Every Vagrant development environment requires a box. You can search for
+# boxes at https://vagrantcloud.com/search.
+boxen = []
+boxen << Box.new("openbsd", "generic/openbsd6", <<~EOF)
+ # install rvm
+ pkg_add gnupg-2.2.12p0
+ gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
+ curl -sSL https://get.rvm.io | bash -s stable
+ source /etc/profile.d/rvm.sh
+ usermod -G rvm vagrant
+
+ # install ruby and build-essentials
+ rvm install ruby-2.7
+EOF
+boxen << Box.new("bionic32", "mkorenkov/ubuntu-bionic32", <<~EOF)
+ export DEBIAN_FRONTEND=noninteractive
+ apt-get update
+ apt-get install -y apt-utils
+ apt-get install -y libxslt-dev libxml2-dev pkg-config
+ apt-get install -y ruby ruby-dev bundler git
+EOF
+boxen << Box.new("freebsd", "freebsd/FreeBSD-13.0-CURRENT", <<~EOF)
+ pkg install rbenv ruby-build
+EOF
+
+Vagrant.configure("2") do |config|
+ boxen.each do |box|
+ config.vm.define(box.shortname) do |config|
+ config.vm.box = box.name
+
+ # Share an additional folder to the guest VM. The first argument is
+ # the path on the host to the actual folder. The second argument is
+ # the path on the guest to mount the folder. And the optional third
+ # argument is a set of non-required options.
+ # config.vm.synced_folder "../data", "/vagrant_data"
+
+ config.vm.provider("virtualbox") do |vb|
+ vb.customize(["modifyvm", :id, "--cpus", 2])
+ vb.customize(["modifyvm", :id, "--memory", 1024])
+ end
+
+ config.vm.synced_folder(".", "/nokogiri")
+
+ if box.provision
+ config.vm.provision("shell", inline: box.provision)
+ end
+ end
+ end
+
+ # Provider-specific configuration so you can fine-tune various
+ # backing providers for Vagrant. These expose provider-specific options.
+ # Example for VirtualBox:
+ #
+ # config.vm.provider "virtualbox" do |vb|
+ # # Display the VirtualBox GUI when booting the machine
+ # vb.gui = true
+ #
+ # # Customize the amount of memory on the VM:
+ # vb.memory = "1024"
+ # end
+ #
+ # View the documentation for the provider you are using for more
+ # information on available options.
+
+ # Enable provisioning with a shell script. Additional provisioners such as
+ # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
+ # documentation for more information about their specific syntax and use.
+ # config.vm.provision "shell", inline: <<-SHELL
+ # apt-get update
+ # apt-get install -y apache2
+ # SHELL
+end
diff --git a/Y_U_NO_GEMSPEC.md b/Y_U_NO_GEMSPEC.md
deleted file mode 100644
index 710e2ae25b..0000000000
--- a/Y_U_NO_GEMSPEC.md
+++ /dev/null
@@ -1,155 +0,0 @@
-(note: this was originally a blog post published at http://blog.flavorjon.es/2012/03/y-u-no-gemspec.html)
-
-## tl;dr
-
-1. Team Nokogiri are not 10-foot-tall code-crunching robots, so `master` is usually unstable.
-2. Unstable code can corrupt your data and crash your application, which would make everybody look bad.
-3. Therefore, the _risk_ associated with using unstable code is severe; for you _and_ for Team Nokogiri.
-4. The absence of a gemspec is a risk mitigation tactic.
-5. You can always ask for an RC release.
-
-
-## Why Isn't There a Gemspec!?
-
-OHAI! Thank you for asking this question!
-
-Team Nokogiri gets asked this pretty frequently. Just a sample from
-the historical record:
-
-* [Issue #274](https://github.com/sparklemotion/nokogiri/issues/274)
-* [Issue #371](https://github.com/sparklemotion/nokogiri/issues/371)
-* [A commit removing nokogiri.gemspec](https://github.com/sparklemotion/nokogiri/commit/7f17a643a05ca381d65131515b54d4a3a61ca2e1#commitcomment-667477)
-* [A nokogiri-talk thread](http://groups.google.com/group/nokogiri-talk/browse_thread/thread/4706b002e492d23f)
-* [Another nokogiri-talk thread](http://groups.google.com/group/nokogiri-talk/browse_thread/thread/0b201bb80ea3eea0)
-
-Sometimes people imply that we've forgotten, or that we don't know how to
-properly manage our codebase. Those people are super fun to respond
-to!
-
-We've gone back and forth a couple of times over the past few years,
-but the current policy of Team Nokogiri is to **not** provide a
-gemspec in the Github repo. This is a conscious choice, not an
-oversight.
-
-
-## But You Didn't Answer the Question!
-
-Ah, I was hoping you wouldn't notice. Well, OK, let's do this, if
-you're serious about it.
-
-I'd like to start by talking about _risk_. Specifically, the risk
-associated with using a known-unstable version of Nokogiri.
-
-
-### Risk
-
-One common way to evaluate the _risk_ of an incident is:
-
- risk = probability x impact
-
-You can read more about this on [the internets](http://en.wikipedia.org/wiki/Risk_Matrix).
-
-The _risk_ associated with a Nokogiri bug could be loosely defined by
-answering the questions:
-
-* "How likely is it that a bug exists?" (probability)
-* "How severe will the consequences of a bug be?" (impact)
-
-
-### Probability
-
-The `master` branch should be considered unstable. Team Nokogiri are
-not 10-foot-tall code-crunching robots; we are humans. We make
-mistakes, and as a result, any arbitrary commit on `master` is likely
-to contain bugs.
-
-Just as an example, Nokogiri `master` was unstable for about five
-months between November 2011 and March 2012. It was unstable not
-because we were sloppy, or didn't care, but because the fixes were
-hard and unobvious.
-
-When we release Nokogiri, we test for memory leaks and invalid memory
-access on all kinds of platforms with many flavors of Ruby and lots of
-versions of libxml2. Because these tests are time-consuming, we don't
-run them on every commit. We run them often when preparing a release.
-
-If we're releasing Nokogiri, it means we think it's rock solid.
-
-And if we're not releasing it, it means there are probably bugs.
-
-
-### Impact
-
-Nokogiri is a gem with native extensions. This means it's not pure
-Ruby -- there's C or Java code being compiled and run, which means
-that there's always a chance that the gem will crash your application,
-or worse. Possible outcomes include:
-
-* leaking memory
-* corrupting data
-* making benign code crash (due to memory corruption)
-
-So, then, a bug in a native extension can have much worse downside
-than you might think. It's not just going to do something unexpected;
-it's possibly going to do terrible, awful things to your application
-and data.
-
-**Nobody** wants that to happen. Especially Team Nokogiri.
-
-
-### Risk, Redux
-
-So, if you accept the equation
-
- risk = probability x impact
-
-and you believe me when I say that:
-
-* the probablility of a bug in unreleased code is high, and
-* the impact of a bug is likely to be severe,
-
-then you should easily see that the _risk_ associated with a bug in
-Nokogiri is quite high.
-
-Part of Team Nokogiri's job is to try to mitigate this risk. We have a
-number of tactics that we use to accomplish this:
-
-* we respond quickly to bug reports, particularly when they are possible memory issues
-* we review each others' commits
-* we have a thorough test suite, and we test-drive new features
-* we discuss code design and issues on a core developer mailing list
-* we use valgrind to test for memory issues (leaks and invalid
- access) on multiple combinations of OS, libxml2 and Ruby
-* we package release candidates, and encourage devs to use them
-* **we do NOT commit a gemspec in our git repository**
-
-Yes, that's right, the absence of a gemspec is a risk mitigation
-tactic. Not only does Team Nokogiri not want to imply support for
-`master`, we want to **actively discourage** people from using
-it. Because it's not stable.
-
-
-## But I Want to Do It Anyway
-
-Another option, is to email the [nokogiri-talk
-list](http://groups.google.com/group/nokogiri-talk) and ask for a
-release candidate to be built. We're pretty accommodating if there's a
-bugfix that's a blocker for you. And if we can't release an RC, we'll
-tell you why.
-
-And in the end, nothing is stopping you from cloning the repo and
-generating a private gemspec. This is an extra step or two, but it has
-the benefit of making sure developers have thought through the costs
-and risks involved; and it tends to select for developers who know
-what they're doing.
-
-
-## In Conclusion
-
-Team Nokogiri takes stability very seriously. We want everybody who
-uses Nokogiri to have a pleasant experience. And so we want to make
-sure that you're using the best software we can make.
-
-Please keep in mind that we're trying very hard to do the right thing
-for all Nokogiri users out there in Rubyland. Nokogiri loves you very
-much, and we hope you love it back.
diff --git a/adr/2022-12-darwin-symbol-resolution.md b/adr/2022-12-darwin-symbol-resolution.md
new file mode 100644
index 0000000000..06cde6472c
--- /dev/null
+++ b/adr/2022-12-darwin-symbol-resolution.md
@@ -0,0 +1,53 @@
+
+# 2022-12 Hide libxml2 and libxslt symbols on Darwin in Ruby 3.2 native gem
+
+## Status
+
+Accepted, but reversible if an alternative technical solution can be found.
+
+
+## Context
+
+In the final days of shipping Nokogiri v1.14.0 with native (precompiled) support for Ruby 3.2, we're struggling a bit with symbol resolution.
+
+Ruby 3.2, when compiling on Darwin, uses the `-bundle_loader` linker flag to resolve symbols against the Ruby executable as if it were a shared library. (This means that, when running a Ruby compiled with the `--enable-shared` flag, that the extension will fail to resolve Ruby symbols like `rb_cObject`.)
+
+We can work around that with the `-flat_namespace` linker flag, which mimics the behavior we already see on Linux and allows us to resolve these symbols at runtime. But for reasons I don't fully understand, many Rubies on Darwin seem to load the libxml2 and libxslt dylibs that ship with XCode commandline tools ("CLT"), and so _every_ libxml2 symbol is a collision and resolves to the _wrong_ libxml2 (not the version we've patched and statically linked into the extension).
+
+To work around this last problem, the best solution we know of right now seems to be to avoid exporting those symbols by using the `-load_hidden` flag (or a similar mechanism, there are several we could choose from).
+
+
+## Decision
+
+Nokogiri v1.14.0's precompiled native gem for Darwin (MacOS) Ruby 3.2 will be built with:
+
+- the `-flat_namespace` flag to ensure the extension can be used by both `--enable-shared` and `--disable-shared` Rubies,
+- and the `-load_hidden` flag for both `libxml2` and `libxslt` to avoid accidentally resolving to non-vendored versions of those libraries
+
+
+## Consequences
+
+This would prevent accidental symbol collisions such as the https://github.com/sparklemotion/nokogiri/pull/2106 on Linux, and would ensure that we always pull in the desired version of libxml2, avoiding problems like the ones we're currently experiencing with Ruby 3.2 (see https://github.com/rake-compiler/rake-compiler-dock/issues/87 for extended discussion and more links).
+
+This would also, however, prevent a small but non-zero number of downstream gems from integrating with Nokogiri's C API, or the C API of libxml2, libxslt, or libgumbo. A notable gem that did this was https://github.com/rubys/nokogumbo (now merged into Nokogiri itself). Another notable gem that I know that does this is `nokogiri-xmlsec` (and the various forks of it, the most popular seems to be https://github.com/instructure/nokogiri-xmlsec-instructure). So this may prevent experimentation and innovation (see Nokogumbo) as well as putting hurdles in front of useful integrations like xmlsec.
+
+
+## Alternatives considered
+
+__Remove the `-bundle_loader` flag from the link line.__ Although this works, it feels a bit like fighting the toolchain and the Ruby core team. It's a bit more complicated of a solution, it's harder for me to reason about, and I'm not positive we won't discover some weird side effect later on.
+
+__Fully hide all symbols everywhere__ is taking the chosen solution to the extreme, and may be what we decide to do in the future (see [RFC: Stop exporting symbols · Discussion #2746 · sparklemotion/nokogiri](https://github.com/sparklemotion/nokogiri/discussions/2746)). For now, though, I'd like to keep our options open and not break compatibility completely in this v1.14.0 release. By only doing this where we're forced to, we have a chance to learn about how the API is being used, and also buy some time to hear feedback and to find an alternative solution.
+
+__Stop precompiling__ or __Stop vendoring libraries__ should always be options we consider, because offering native gems and vendoring libraries introduces complexity. However, I covered many of the reasons I think it's good for Nokogiri to do this in [my RubyConf 2021 talk titled "Building Native Extensions. This Could Take A While..."](https://www.youtube.com/watch?v=jtpOci5o50g) and those reasons are still valid, notably our ability to patch libxml2 for performance (see [#2144](https://github.com/sparklemotion/nokogiri/pull/2144)), functional (see [#2403](https://github.com/sparklemotion/nokogiri/pull/2403)), or security (see [#2294](https://github.com/sparklemotion/nokogiri/pull/2294)) reasons.
+
+
+## References
+
+- Ruby commit introducing `-bundle_loader`: https://github.com/ruby/ruby/commit/50d81bf
+- The PR implementing this decision is [dep: add ruby 3.2 support by flavorjones · Pull Request #2732 · sparklemotion/nokogiri](https://github.com/sparklemotion/nokogiri/pull/2732)
+- Future symbol visibility decision will be made at [RFC: Stop exporting symbols · Discussion #2746 · sparklemotion/nokogiri](https://github.com/sparklemotion/nokogiri/discussions/2746)
+- Background context and solution details at
+ - [[Ruby 3.2] having runtime issues on darwin · Issue #87 · rake-compiler/rake-compiler-dock](https://github.com/rake-compiler/rake-compiler-dock/issues/87)
+ - https://github.com/stevecheckoway/bundle_test
+ - [explore whether \`-load\_hidden\` will work around flat namespace by flavorjones · Pull Request #1 · stevecheckoway/bundle\_test](https://github.com/stevecheckoway/bundle_test/pull/1)
+- [Video from Apple explaining the Darwin toolchain changes](https://developer.apple.com/videos/play/wwdc2022/110362/)
diff --git a/appveyor.yml b/appveyor.yml
index 188ad24307..15a26bf37d 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,19 @@
+image: Visual Studio 2019
+
+branches:
+ only:
+ - main
+
+skip_branch_with_pr: true
+
+clone_depth: 1
+
+cache:
+ - vendor/bundle
+ - ports/archives
+
install:
+ - IF DEFINED INSTALL_PACKAGES ( ridk exec pacman --noconfirm --needed --sync %INSTALL_PACKAGES% )
- SET PATH=C:\ruby%ruby_version%\bin;%PATH%
- ps: |
if ($env:ruby_version -like "*head*") {
@@ -8,8 +23,9 @@ install:
- ruby --version
- gem --version
- gem install bundler --conservative
+ - git submodule update --init
+ - bundle config --local path vendor/bundle
- bundle install
- - IF DEFINED INSTALL_PACKAGES ( ridk exec pacman --noconfirm --needed --sync %INSTALL_PACKAGES% )
build: off
@@ -18,16 +34,14 @@ test_script:
environment:
matrix:
- - ruby_version: head-x64
- INSTALL_PACKAGES: "mingw-w64-x86_64-libxslt"
+ - ruby_version: 31
+ INSTALL_PACKAGES: "mingw-w64-i686-libyaml"
+ - ruby_version: 31
+ INSTALL_PACKAGES: "mingw-w64-i686-libxslt mingw-w64-i686-libyaml"
EXTCONF_PARAMS: "--use-system-libraries"
- - ruby_version: 26
- - ruby_version: 25-x64
- - ruby_version: 24
- INSTALL_PACKAGES: "mingw-w64-i686-libxslt"
- EXTCONF_PARAMS: "--use-system-libraries"
- - ruby_version: 23-x64
-matrix:
- allow_failures:
- - ruby_version: head
+ - ruby_version: 27
+ INSTALL_PACKAGES: "mingw-w64-i686-libyaml"
+ - ruby_version: 27
+ INSTALL_PACKAGES: "mingw-w64-i686-libxslt mingw-w64-i686-libyaml"
+ EXTCONF_PARAMS: "--use-system-libraries"
diff --git a/bin/nokogiri b/bin/nokogiri
index 60b1eb3cea..04a5ceae19 100755
--- a/bin/nokogiri
+++ b/bin/nokogiri
@@ -1,61 +1,77 @@
#!/usr/bin/env ruby
-require 'optparse'
-require 'open-uri'
-require 'uri'
-require 'rubygems'
-require 'nokogiri'
-autoload :IRB, 'irb'
+# frozen_string_literal: true
+
+require "optparse"
+require "open-uri"
+require "uri"
+require "rubygems"
+require "nokogiri"
+autoload :IRB, "irb"
parse_class = Nokogiri
encoding = nil
# This module provides some tunables with the nokogiri CLI for use in
# your ~/.nokogirirc.
-module Nokogiri::CLI
- class << self
- # Specify the console engine, defaulted to IRB.
- #
- # call-seq:
- # require 'pry'
- # Nokogiri::CLI.console = Pry
- attr_writer :console
-
- def console
- case @console
- when Symbol
- Kernel.const_get(@console)
- else
- @console
+module Nokogiri
+ module CLI
+ class << self
+ # Specify the console engine, defaulted to IRB.
+ #
+ # call-seq:
+ # require 'pry'
+ # Nokogiri::CLI.console = Pry
+ attr_writer :console
+
+ def console
+ case @console
+ when Symbol
+ Kernel.const_get(@console)
+ else
+ @console
+ end
end
+
+ attr_accessor :rcfile
end
- attr_accessor :rcfile
+ self.rcfile = File.expand_path("~/.nokogirirc")
+ self.console = :IRB
end
+end
- self.rcfile = File.expand_path('~/.nokogirirc')
- self.console = :IRB
+def safe_read(uri_or_path)
+ uri = URI.parse(uri_or_path)
+ case uri
+ when URI::HTTP
+ uri.read
+ when URI::File
+ File.read(uri.path)
+ else
+ File.read(uri_or_path)
+ end
end
opts = OptionParser.new do |opts|
opts.banner = "Nokogiri: an HTML, XML, SAX, and Reader parser"
- opts.define_head "Usage: nokogiri [options]"
- opts.separator ""
- opts.separator "Examples:"
- opts.separator " nokogiri https://www.ruby-lang.org/"
- opts.separator " nokogiri ./public/index.html"
- opts.separator " curl -s http://www.nokogiri.org | nokogiri -e'p $_.css(\"h1\").length'"
- opts.separator ""
- opts.separator "Options:"
+ opts.define_head("Usage: nokogiri [options]")
+ opts.separator("")
+ opts.separator("Examples:")
+ opts.separator(" nokogiri https://www.ruby-lang.org/")
+ opts.separator(" nokogiri ./public/index.html")
+ opts.separator(" curl -s http://www.nokogiri.org | nokogiri -e'p $_.css(\"h1\").length'")
+ opts.separator("")
+ opts.separator("Options:")
opts.on("--type type", "Parse as type: xml or html (default: auto)", [:xml, :html]) do |v|
- parse_class = {:xml => Nokogiri::XML, :html => Nokogiri::HTML}[v]
+ parse_class = { xml: Nokogiri::XML, html: Nokogiri::HTML }[v]
end
opts.on("-C file", "Specifies initialization file to load (default #{Nokogiri::CLI.rcfile})") do |v|
Nokogiri::CLI.rcfile = v
end
- opts.on("-E", "--encoding encoding", "Read as encoding (default: #{encoding || 'none'})") do |v|
+ opts.on("-E", "--encoding encoding", "Read as encoding (default: #{encoding || "none"})") do |v|
encoding = v
end
@@ -64,7 +80,7 @@ opts = OptionParser.new do |opts|
end
opts.on("--rng ", "Validate using this rng file.") do |v|
- @rng = open(v) {|f| Nokogiri::XML::RelaxNG(f)}
+ @rng = Nokogiri::XML::RelaxNG(safe_read(v))
end
opts.on_tail("-?", "--help", "Show this message") do
@@ -90,15 +106,10 @@ if File.file?(Nokogiri::CLI.rcfile)
load Nokogiri::CLI.rcfile
end
-if url || $stdin.tty?
- case uri = (URI(url) rescue url)
- when URI::HTTP
- @doc = parse_class.parse(uri.read, url, encoding)
- else
- @doc = parse_class.parse(open(url).read, nil, encoding)
- end
+@doc = if url || $stdin.tty?
+ parse_class.parse(safe_read(url), url, encoding)
else
- @doc = parse_class.parse($stdin, nil, encoding)
+ parse_class.parse($stdin, nil, encoding)
end
$_ = @doc
@@ -107,12 +118,14 @@ if @rng
@rng.validate(@doc).each do |error|
puts error.message
end
-else
- if @script
- eval @script, binding, ''
- else
- puts "Your document is stored in @doc..."
- Nokogiri::CLI.console.start
+elsif @script
+ begin
+ eval(@script, binding, "") # rubocop:disable Security/Eval
+ rescue Exception => e # rubocop:disable Lint/RescueException
+ warn("ERROR: Exception raised while evaluating '#{@script}'")
+ raise e
end
+else
+ puts "Your document is stored in @doc..."
+ Nokogiri::CLI.console.start
end
-
diff --git a/build_all b/build_all
deleted file mode 100755
index f7f6e99792..0000000000
--- a/build_all
+++ /dev/null
@@ -1,24 +0,0 @@
-#! /usr/bin/env bash
-#
-# script to build gems for all relevant platforms
-#
-set -o errexit
-
-rm -rf tmp pkg gems
-mkdir -p gems
-
-# MRI et al (standard gem)
-bundle exec rake clean
-bundle exec rake compile test
-bundle exec rake gem
-cp -v pkg/nokogiri*.gem gems
-
-# jruby
-bundle exec rake clean
-bundle exec rake gem:jruby
-cp -v pkg/nokogiri*java.gem gems
-
-# windows (x86-mingw32 and x64-mingw32)
-bundle exec rake clean
-bundle exec rake gem:windows
-cp -v pkg/nokogiri*{x86,x64}-mingw32*.gem gems
diff --git a/concourse/TODO.md b/concourse/TODO.md
deleted file mode 100644
index 30e7af6019..0000000000
--- a/concourse/TODO.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# nokogiri concourse to-do
-
-## concourse.yml
-
-* [x] real ssl cert
-* [x] github authentication
-* [x] bastion host
-* [x] upgrade bbl
-
-## nokogiri.yml
-
-* [x] test using system libraries
-* [x] handle pull requests
-* [x] run windows tests under devkit
-* [ ] osx
- * system
- * system-homebrew
- * vendored
-* [ ] build an rc gem and upload to rubygems [→ rubygems resource]
- * should always check manifest
-* install gem and test:
- * [ ] osx
- * [ ] linux (system)
- * [ ] linux (vendored)
- * [ ] linux (vendored, --disable-static)
- * [ ] OpenSuse with site_config (lib64, #1562)
- * [ ] windows (fat binary)
- * [ ] windows (devkit)
-* notifications on failure / success
- * [x] irc [→ irc resource]
-
-## other projects
-
-* [x] pipeline: mini_portile [→ bosh release]
-* [x] pipeline: chromedriver-helper
-* [x] bosh release for windows worker config:
- * [ ] ruby of all supported versions
- * [ ] devkit installed in all rubies
- * [ ] cmake
-* [x] resource: irc
-* [ ] resource: rubygems
-
-## nokogiri stretch goals
-
-* [ ] get openbsd / freebsd / etc. people to donate worker machines
-* [ ] use an S3 bucket for sub-artifacts:
- * source tarballs
- * compiled .dlls
diff --git a/concourse/common_anchors.yml b/concourse/common_anchors.yml
deleted file mode 100644
index ee4a092c15..0000000000
--- a/concourse/common_anchors.yml
+++ /dev/null
@@ -1,3 +0,0 @@
- notify_failure_to_irc: ¬ify_failure_to_irc
- put: nokogiri-irc
- params: {message: "($BUILD_PIPELINE_NAME/$BUILD_JOB_NAME) The build failed ($BUILD_URL)"}
diff --git a/concourse/common_prelude.rb b/concourse/common_prelude.rb
deleted file mode 100644
index dcae14a7a9..0000000000
--- a/concourse/common_prelude.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require 'json'
-
-$common_ignore_paths = [
- "CHANGELOG.md",
- "README.md",
- "concourse/**",
- "suppressions/**",
-].to_json
diff --git a/concourse/common_resource_types.yml b/concourse/common_resource_types.yml
deleted file mode 100644
index 54f1679843..0000000000
--- a/concourse/common_resource_types.yml
+++ /dev/null
@@ -1,4 +0,0 @@
- - name: irc-notification
- type: docker-image
- source:
- repository: flavorjones/irc-notification-resource
diff --git a/concourse/common_resources.yml b/concourse/common_resources.yml
deleted file mode 100644
index 95016f27c0..0000000000
--- a/concourse/common_resources.yml
+++ /dev/null
@@ -1,16 +0,0 @@
- - name: ci
- type: git
- icon: "settings"
- source:
- uri: https://github.com/sparklemotion/nokogiri/
- branch: master
- disable_ci_skip: true # always get the latest pipeline configuration
- - name: nokogiri-irc
- type: irc-notification
- icon: "bell"
- source:
- server: chat.freenode.net
- port: 7070
- channel: "#nokogiri"
- user: {{nokobot-irc-username}}
- password: {{nokobot-irc-password}}
diff --git a/concourse/images/Dockerfile.jruby.erb b/concourse/images/Dockerfile.jruby.erb
deleted file mode 100644
index 49c8ac2ae9..0000000000
--- a/concourse/images/Dockerfile.jruby.erb
+++ /dev/null
@@ -1,7 +0,0 @@
-FROM jruby:<%= version %>-jdk
-
-<%= File.read "java-opts.step" %>
-
-<%= File.read "update-bundler.step" %>
-
-<%= File.read "bundle-install.step" %>
diff --git a/concourse/images/Dockerfile.mri.erb b/concourse/images/Dockerfile.mri.erb
deleted file mode 100644
index e93e24f9be..0000000000
--- a/concourse/images/Dockerfile.mri.erb
+++ /dev/null
@@ -1,11 +0,0 @@
-FROM ruby:<%= version %>
-
-<%= File.read "debian-prelude.step" %>
-
-<%= File.read "debian-valgrind.step" %>
-
-<%= File.read "debian-libxml-et-al.step" %>
-
-<%= File.read "update-bundler.step" %>
-
-<%= File.read "bundle-install.step" %>
diff --git a/concourse/images/Dockerfile.xenial.erb b/concourse/images/Dockerfile.xenial.erb
deleted file mode 100644
index ee6f2b235c..0000000000
--- a/concourse/images/Dockerfile.xenial.erb
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM ubuntu:xenial
-
-<%= File.read "debian-prelude.step" %>
-
-<%= File.read "debian-libxml-et-al.step" %>
-
-<%= File.read "debian-ruby.step" %>
-
-<%= File.read "bundle-install.step" %>
diff --git a/concourse/images/bundle-install.step b/concourse/images/bundle-install.step
deleted file mode 100644
index 70c1cf4e6b..0000000000
--- a/concourse/images/bundle-install.step
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- dockerfile -*-
-
-COPY Gemfile nokogiri/
-COPY Gemfile.lock nokogiri/
-
-RUN gem install bundler
-RUN cd nokogiri && bundle install
diff --git a/concourse/images/debian-libxml-et-al.step b/concourse/images/debian-libxml-et-al.step
deleted file mode 100644
index 5f73f12f3b..0000000000
--- a/concourse/images/debian-libxml-et-al.step
+++ /dev/null
@@ -1,3 +0,0 @@
-# -*- dockerfile -*-
-
-RUN apt-get install -y libxslt-dev libxml2-dev pkg-config
diff --git a/concourse/images/java-opts.step b/concourse/images/java-opts.step
deleted file mode 100644
index cc7d0c7747..0000000000
--- a/concourse/images/java-opts.step
+++ /dev/null
@@ -1,4 +0,0 @@
-# -*- dockerfile -*-
-
-# https://github.com/docker-library/openjdk/issues/32
-ENV JAVA_OPTS="-Dfile.encoding=UTF8"
diff --git a/concourse/nokogiri-pr.yml b/concourse/nokogiri-pr.yml
deleted file mode 100644
index f407049394..0000000000
--- a/concourse/nokogiri-pr.yml
+++ /dev/null
@@ -1,344 +0,0 @@
-% require "common_prelude.rb"
-
-resource_types:
-<%= erbify_file "common_resource_types.yml" -%>
- - name: pull-request
- type: docker-image
- source:
- repository: jtarchie/pr
-
-
-resources:
-<%= erbify_file "common_resources.yml" -%>
- - name: nokogiri-pr
- type: pull-request
- icon: "github-circle"
- source:
- repo: sparklemotion/nokogiri
- access_token: {{github-repo-status-access-token}}
- ignore_paths: <%= $common_ignore_paths %>
-
-
-anchors:
-<%= erbify_file "common_anchors.yml" -%>
- notify_failure_to_pr: ¬ify_failure_to_pr
- put: nokogiri-pr
- params: {path: nokogiri-pr, status: failure}
-
-
-jobs:
- - name: pr-pending
- public: true
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- - put: nokogiri-pr
- params: {path: nokogiri-pr, status: pending}
-
-
-% Concourse.production_rubies.each do |ruby_version|
- - name: ruby-<%= ruby_version %>-system
- public: true
- serial_groups: ["ruby-<%= ruby_version %>"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
-% if ruby_version == Concourse.production_rubies.last
- passed: [pr-pending]
-% else
- passed: ["ruby-<%= Concourse.production_rubies.last %>-system"]
-% end
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-<%= ruby_version %>"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
-% if ruby_version == Concourse.production_rubies.last
- CC_TEST_REPORTER_ID: {{code_climate_reporter_id_nokogiri}}
-% end
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-<%= ruby_version %>-vendored
- public: true
- serial_groups: ["ruby-<%= ruby_version %>"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["ruby-<%= ruby_version %>-system"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-<%= ruby_version %>"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-<%= ruby_version %>-valgrind
- public: true
- serial_groups: ["ruby-<%= ruby_version %>"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["ruby-<%= ruby_version %>-vendored"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-<%= ruby_version %>"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- TEST_WITH_VALGRIND: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-% end
-
-
-% RUBIES[:jruby].each_with_index do |jruby_version, j|
- - name: jruby-<%= jruby_version %>
- public: true
- serial_groups: ["jruby"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
-% if j > 0
- passed: ["jruby-<%= RUBIES[:jruby][j-1] %>"]
-% else
- passed: ["ruby-<%= Concourse.production_rubies.last %>-system"]
-% end
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "jruby-<%= jruby_version %>"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-% end
-
- - name: gate
- public: true
- plan:
- - get: nokogiri-pr
- trigger: true
- version: every
- passed:
-% Concourse.production_rubies.each do |ruby_version|
- - "ruby-<%= ruby_version %>-valgrind"
-% end
- - "jruby-<%= RUBIES[:jruby].last %>"
-
-
- - name: gem-test
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["gate"]
- - task: gem-build
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-<%= Concourse.production_rubies.last %>"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- outputs:
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-build.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
- - task: gem-install-and-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-<%= Concourse.production_rubies.last %>"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-install-and-test.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
- - name: gem-test-java
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["gate"]
- - task: gem-build
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "jruby-<%= RUBIES[:jruby].last %>"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- outputs:
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-build-java.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
- - task: gem-install-and-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "jruby-<%= RUBIES[:jruby].last %>"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-install-and-test.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-vanilla-system
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["gate"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: xenial}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- TEST_WITH_APT_REPO_RUBY: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-libxmlruby-system
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["gate"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-<%= Concourse.production_rubies.last %>"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- BUNDLE_GEMFILE: "Gemfile-libxml-ruby"
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-libxmlruby-valgrind
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["gate"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-<%= Concourse.production_rubies.last %>"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- BUNDLE_GEMFILE: "Gemfile-libxml-ruby"
- TEST_WITH_VALGRIND: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: pr-success
- public: true
- disable_manual_trigger: true
- plan:
- - get: nokogiri-pr
- trigger: true
- version: every
- passed:
- - ruby-vanilla-system
- - ruby-libxmlruby-system
- - ruby-libxmlruby-valgrind
- - gem-test
- - gem-test-java
- - put: nokogiri-pr
- params: {path: nokogiri-pr, status: success}
- - put: nokogiri-irc
- params: {message: "($BUILD_PIPELINE_NAME/$BUILD_JOB_NAME) The build passed ($BUILD_URL)"}
diff --git a/concourse/nokogiri-pr.yml.generated b/concourse/nokogiri-pr.yml.generated
deleted file mode 100644
index d474cd5d7f..0000000000
--- a/concourse/nokogiri-pr.yml.generated
+++ /dev/null
@@ -1,594 +0,0 @@
-
-resource_types:
- - name: irc-notification
- type: docker-image
- source:
- repository: flavorjones/irc-notification-resource
- - name: pull-request
- type: docker-image
- source:
- repository: jtarchie/pr
-
-
-resources:
- - name: ci
- type: git
- icon: "settings"
- source:
- uri: https://github.com/sparklemotion/nokogiri/
- branch: master
- disable_ci_skip: true # always get the latest pipeline configuration
- - name: nokogiri-irc
- type: irc-notification
- icon: "bell"
- source:
- server: chat.freenode.net
- port: 7070
- channel: "#nokogiri"
- user: {{nokobot-irc-username}}
- password: {{nokobot-irc-password}}
- - name: nokogiri-pr
- type: pull-request
- icon: "github-circle"
- source:
- repo: sparklemotion/nokogiri
- access_token: {{github-repo-status-access-token}}
- ignore_paths: ["CHANGELOG.md","README.md","concourse/**","suppressions/**"]
-
-
-anchors:
- notify_failure_to_irc: ¬ify_failure_to_irc
- put: nokogiri-irc
- params: {message: "($BUILD_PIPELINE_NAME/$BUILD_JOB_NAME) The build failed ($BUILD_URL)"}
- notify_failure_to_pr: ¬ify_failure_to_pr
- put: nokogiri-pr
- params: {path: nokogiri-pr, status: failure}
-
-
-jobs:
- - name: pr-pending
- public: true
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- - put: nokogiri-pr
- params: {path: nokogiri-pr, status: pending}
-
-
- - name: ruby-2.3-system
- public: true
- serial_groups: ["ruby-2.3"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["ruby-2.6-system"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.3"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-2.3-vendored
- public: true
- serial_groups: ["ruby-2.3"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["ruby-2.3-system"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.3"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-2.3-valgrind
- public: true
- serial_groups: ["ruby-2.3"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["ruby-2.3-vendored"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.3"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- TEST_WITH_VALGRIND: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
- - name: ruby-2.4-system
- public: true
- serial_groups: ["ruby-2.4"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["ruby-2.6-system"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.4"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-2.4-vendored
- public: true
- serial_groups: ["ruby-2.4"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["ruby-2.4-system"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.4"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-2.4-valgrind
- public: true
- serial_groups: ["ruby-2.4"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["ruby-2.4-vendored"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.4"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- TEST_WITH_VALGRIND: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
- - name: ruby-2.5-system
- public: true
- serial_groups: ["ruby-2.5"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["ruby-2.6-system"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.5"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-2.5-vendored
- public: true
- serial_groups: ["ruby-2.5"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["ruby-2.5-system"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.5"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-2.5-valgrind
- public: true
- serial_groups: ["ruby-2.5"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["ruby-2.5-vendored"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.5"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- TEST_WITH_VALGRIND: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
- - name: ruby-2.6-system
- public: true
- serial_groups: ["ruby-2.6"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: [pr-pending]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.6"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- CC_TEST_REPORTER_ID: {{code_climate_reporter_id_nokogiri}}
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-2.6-vendored
- public: true
- serial_groups: ["ruby-2.6"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["ruby-2.6-system"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.6"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-2.6-valgrind
- public: true
- serial_groups: ["ruby-2.6"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["ruby-2.6-vendored"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.6"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- TEST_WITH_VALGRIND: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: jruby-9.1
- public: true
- serial_groups: ["jruby"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["ruby-2.6-system"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "jruby-9.1"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
- - name: jruby-9.2
- public: true
- serial_groups: ["jruby"]
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["jruby-9.1"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "jruby-9.2"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
- - name: gate
- public: true
- plan:
- - get: nokogiri-pr
- trigger: true
- version: every
- passed:
- - "ruby-2.3-valgrind"
- - "ruby-2.4-valgrind"
- - "ruby-2.5-valgrind"
- - "ruby-2.6-valgrind"
- - "jruby-9.2"
-
-
- - name: gem-test
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["gate"]
- - task: gem-build
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.6"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- outputs:
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-build.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
- - task: gem-install-and-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.6"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-install-and-test.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
- - name: gem-test-java
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["gate"]
- - task: gem-build
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "jruby-9.2"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- outputs:
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-build-java.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
- - task: gem-install-and-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "jruby-9.2"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-install-and-test.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-vanilla-system
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["gate"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: xenial}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- TEST_WITH_APT_REPO_RUBY: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-libxmlruby-system
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["gate"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.6"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- BUNDLE_GEMFILE: "Gemfile-libxml-ruby"
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: ruby-libxmlruby-valgrind
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri-pr
- trigger: true
- version: every
- passed: ["gate"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.6"}
- inputs:
- - name: ci
- - name: nokogiri-pr
- path: nokogiri
- params:
- BUNDLE_GEMFILE: "Gemfile-libxml-ruby"
- TEST_WITH_VALGRIND: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: { aggregate: [*notify_failure_to_irc, *notify_failure_to_pr] }
-
-
- - name: pr-success
- public: true
- disable_manual_trigger: true
- plan:
- - get: nokogiri-pr
- trigger: true
- version: every
- passed:
- - ruby-vanilla-system
- - ruby-libxmlruby-system
- - ruby-libxmlruby-valgrind
- - gem-test
- - gem-test-java
- - put: nokogiri-pr
- params: {path: nokogiri-pr, status: success}
- - put: nokogiri-irc
- params: {message: "($BUILD_PIPELINE_NAME/$BUILD_JOB_NAME) The build passed ($BUILD_URL)"}
diff --git a/concourse/nokogiri.yml b/concourse/nokogiri.yml
deleted file mode 100644
index 4b5f2f1d93..0000000000
--- a/concourse/nokogiri.yml
+++ /dev/null
@@ -1,302 +0,0 @@
-% require "common_prelude.rb"
-
-resource_types:
-<%= erbify_file "common_resource_types.yml" -%>
-
-
-resources:
-<%= erbify_file "common_resources.yml" -%>
- - name: nokogiri
- type: git
- icon: "github-circle"
- source:
- uri: https://github.com/sparklemotion/nokogiri/
- branch: master
- ignore_paths: <%= $common_ignore_paths %>
-
-
-anchors:
-<%= erbify_file "common_anchors.yml" -%>
-
-
-jobs:
-% RUBIES[:mri].each do |ruby_version|
- - name: ruby-<%= ruby_version %>-system
- public: true
- serial_groups: ["ruby-<%= ruby_version %>"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-<%= ruby_version %>"}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
-% if ruby_version == Concourse.production_rubies.last
- CC_TEST_REPORTER_ID: {{code_climate_reporter_id_nokogiri}}
- GIT_BRANCH: master
-% end
- run:
- path: ci/concourse/tasks/rake-test/run.sh
-% if Concourse.production_rubies.include? ruby_version
- on_failure: *notify_failure_to_irc
-% end
-
- - name: ruby-<%= ruby_version %>-vendored
- public: true
- serial_groups: ["ruby-<%= ruby_version %>"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["ruby-<%= ruby_version %>-system"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-<%= ruby_version %>"}
- inputs:
- - name: ci
- - name: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
-% if Concourse.production_rubies.include? ruby_version
- on_failure: *notify_failure_to_irc
-% end
-
- - name: ruby-<%= ruby_version %>-valgrind
- public: true
- serial_groups: ["ruby-<%= ruby_version %>"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["ruby-<%= ruby_version %>-vendored"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-<%= ruby_version %>"}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- TEST_WITH_VALGRIND: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
-% if Concourse.production_rubies.include? ruby_version
- on_failure: *notify_failure_to_irc
-% end
-% end
-
-
-% RUBIES[:jruby].each_with_index do |jruby_version, j|
- - name: jruby-<%= jruby_version %>
- public: true
- serial_groups: ["jruby"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
-% if j > 0
- passed: ["jruby-<%= RUBIES[:jruby][j-1] %>"]
-% end
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "jruby-<%= jruby_version %>"}
- inputs:
- - name: ci
- - name: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-% end
-
-
- - name: gate
- public: true
- plan:
- - get: nokogiri
- trigger: true
- passed:
-% Concourse.production_rubies.each do |ruby_version|
- - "ruby-<%= ruby_version %>-valgrind"
-% end
- - "jruby-<%= RUBIES[:jruby].last %>"
-
-
- - name: ruby-vanilla-system
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["gate"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: xenial}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- TEST_WITH_APT_REPO_RUBY: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
-
- - name: ruby-libxmlruby-system
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["gate"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-<%= Concourse.production_rubies.last %>"}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- BUNDLE_GEMFILE: "Gemfile-libxml-ruby"
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
-
- - name: ruby-libxmlruby-valgrind
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["gate"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-<%= Concourse.production_rubies.last %>"}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- BUNDLE_GEMFILE: "Gemfile-libxml-ruby"
- TEST_WITH_VALGRIND: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
-
- - name: gem-test
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["gate"]
- - task: gem-build
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-<%= Concourse.production_rubies.last %>"}
- inputs:
- - name: ci
- - name: nokogiri
- outputs:
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-build.sh
- on_failure: *notify_failure_to_irc
- - task: gem-install-and-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-<%= Concourse.production_rubies.last %>"}
- inputs:
- - name: ci
- - name: nokogiri
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-install-and-test.sh
- on_failure: *notify_failure_to_irc
-
- - name: gem-test-java
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["gate"]
- - task: gem-build
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "jruby-<%= RUBIES[:jruby].last %>"}
- inputs:
- - name: ci
- - name: nokogiri
- outputs:
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-build-java.sh
- on_failure: *notify_failure_to_irc
- - task: gem-install-and-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "jruby-<%= RUBIES[:jruby].last %>"}
- inputs:
- - name: ci
- - name: nokogiri
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-install-and-test.sh
- on_failure: *notify_failure_to_irc
-
-
- - name: build-success
- public: true
- disable_manual_trigger: true
- plan:
- - get: nokogiri
- trigger: true
- version: every
- passed:
- - ruby-vanilla-system
- - ruby-libxmlruby-system
- - ruby-libxmlruby-valgrind
- - gem-test
- - gem-test-java
- - put: nokogiri-irc
- params: {message: "($BUILD_PIPELINE_NAME/$BUILD_JOB_NAME) The build passed ($BUILD_URL)"}
diff --git a/concourse/nokogiri.yml.generated b/concourse/nokogiri.yml.generated
deleted file mode 100644
index 5cea73d377..0000000000
--- a/concourse/nokogiri.yml.generated
+++ /dev/null
@@ -1,522 +0,0 @@
-
-resource_types:
- - name: irc-notification
- type: docker-image
- source:
- repository: flavorjones/irc-notification-resource
-
-
-resources:
- - name: ci
- type: git
- icon: "settings"
- source:
- uri: https://github.com/sparklemotion/nokogiri/
- branch: master
- disable_ci_skip: true # always get the latest pipeline configuration
- - name: nokogiri-irc
- type: irc-notification
- icon: "bell"
- source:
- server: chat.freenode.net
- port: 7070
- channel: "#nokogiri"
- user: {{nokobot-irc-username}}
- password: {{nokobot-irc-password}}
- - name: nokogiri
- type: git
- icon: "github-circle"
- source:
- uri: https://github.com/sparklemotion/nokogiri/
- branch: master
- ignore_paths: ["CHANGELOG.md","README.md","concourse/**","suppressions/**"]
-
-
-anchors:
- notify_failure_to_irc: ¬ify_failure_to_irc
- put: nokogiri-irc
- params: {message: "($BUILD_PIPELINE_NAME/$BUILD_JOB_NAME) The build failed ($BUILD_URL)"}
-
-
-jobs:
- - name: ruby-2.3-system
- public: true
- serial_groups: ["ruby-2.3"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.3"}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
- - name: ruby-2.3-vendored
- public: true
- serial_groups: ["ruby-2.3"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["ruby-2.3-system"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.3"}
- inputs:
- - name: ci
- - name: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
- - name: ruby-2.3-valgrind
- public: true
- serial_groups: ["ruby-2.3"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["ruby-2.3-vendored"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.3"}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- TEST_WITH_VALGRIND: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
- - name: ruby-2.4-system
- public: true
- serial_groups: ["ruby-2.4"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.4"}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
- - name: ruby-2.4-vendored
- public: true
- serial_groups: ["ruby-2.4"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["ruby-2.4-system"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.4"}
- inputs:
- - name: ci
- - name: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
- - name: ruby-2.4-valgrind
- public: true
- serial_groups: ["ruby-2.4"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["ruby-2.4-vendored"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.4"}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- TEST_WITH_VALGRIND: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
- - name: ruby-2.5-system
- public: true
- serial_groups: ["ruby-2.5"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.5"}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
- - name: ruby-2.5-vendored
- public: true
- serial_groups: ["ruby-2.5"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["ruby-2.5-system"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.5"}
- inputs:
- - name: ci
- - name: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
- - name: ruby-2.5-valgrind
- public: true
- serial_groups: ["ruby-2.5"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["ruby-2.5-vendored"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.5"}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- TEST_WITH_VALGRIND: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
- - name: ruby-2.6-system
- public: true
- serial_groups: ["ruby-2.6"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.6"}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- CC_TEST_REPORTER_ID: {{code_climate_reporter_id_nokogiri}}
- GIT_BRANCH: master
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
- - name: ruby-2.6-vendored
- public: true
- serial_groups: ["ruby-2.6"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["ruby-2.6-system"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.6"}
- inputs:
- - name: ci
- - name: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
- - name: ruby-2.6-valgrind
- public: true
- serial_groups: ["ruby-2.6"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["ruby-2.6-vendored"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.6"}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- TEST_WITH_VALGRIND: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
-
- - name: jruby-9.1
- public: true
- serial_groups: ["jruby"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "jruby-9.1"}
- inputs:
- - name: ci
- - name: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
- - name: jruby-9.2
- public: true
- serial_groups: ["jruby"]
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["jruby-9.1"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "jruby-9.2"}
- inputs:
- - name: ci
- - name: nokogiri
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
-
- - name: gate
- public: true
- plan:
- - get: nokogiri
- trigger: true
- passed:
- - "ruby-2.3-valgrind"
- - "ruby-2.4-valgrind"
- - "ruby-2.5-valgrind"
- - "ruby-2.6-valgrind"
- - "jruby-9.2"
-
-
- - name: ruby-vanilla-system
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["gate"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: xenial}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- TEST_WITH_APT_REPO_RUBY: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
-
- - name: ruby-libxmlruby-system
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["gate"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.6"}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- BUNDLE_GEMFILE: "Gemfile-libxml-ruby"
- NOKOGIRI_USE_SYSTEM_LIBRARIES: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
-
- - name: ruby-libxmlruby-valgrind
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["gate"]
- - task: rake-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.6"}
- inputs:
- - name: ci
- - name: nokogiri
- params:
- BUNDLE_GEMFILE: "Gemfile-libxml-ruby"
- TEST_WITH_VALGRIND: t
- run:
- path: ci/concourse/tasks/rake-test/run.sh
- on_failure: *notify_failure_to_irc
-
-
- - name: gem-test
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["gate"]
- - task: gem-build
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.6"}
- inputs:
- - name: ci
- - name: nokogiri
- outputs:
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-build.sh
- on_failure: *notify_failure_to_irc
- - task: gem-install-and-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "mri-2.6"}
- inputs:
- - name: ci
- - name: nokogiri
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-install-and-test.sh
- on_failure: *notify_failure_to_irc
-
- - name: gem-test-java
- public: true
- serial: true
- plan:
- - get: ci
- - get: nokogiri
- trigger: true
- passed: ["gate"]
- - task: gem-build
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "jruby-9.2"}
- inputs:
- - name: ci
- - name: nokogiri
- outputs:
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-build-java.sh
- on_failure: *notify_failure_to_irc
- - task: gem-install-and-test
- config:
- platform: linux
- image_resource:
- type: docker-image
- source: {repository: "flavorjones/nokogiri-test", tag: "jruby-9.2"}
- inputs:
- - name: ci
- - name: nokogiri
- - name: gems
- run:
- path: ci/concourse/tasks/gem-test/gem-install-and-test.sh
- on_failure: *notify_failure_to_irc
-
-
- - name: build-success
- public: true
- disable_manual_trigger: true
- plan:
- - get: nokogiri
- trigger: true
- version: every
- passed:
- - ruby-vanilla-system
- - ruby-libxmlruby-system
- - ruby-libxmlruby-valgrind
- - gem-test
- - gem-test-java
- - put: nokogiri-irc
- params: {message: "($BUILD_PIPELINE_NAME/$BUILD_JOB_NAME) The build passed ($BUILD_URL)"}
diff --git a/concourse/shared/code-climate.sh b/concourse/shared/code-climate.sh
deleted file mode 100644
index 48c283259d..0000000000
--- a/concourse/shared/code-climate.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Source this file to have access to two functions:
-#
-# code-climate-setup
-#
-# * downloads the CC CLI
-# * sets up CC environment variables
-# * invokes CC's `before-build`
-#
-#
-# code-climate-shipit
-#
-# * invokes CC's `after-build`
-#
-# Note that the env var CC_TEST_REPORTER_ID will need to be set. You
-# can find this on your Code Climate project's "Repo Settings" page.
-#
-
-CC_CLI_URI="https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64"
-CC_CLI=$(basename ${CC_CLI_URI})
-
-function code-climate-setup {
- if [ -z "${CC_TEST_REPORTER_ID:-}" ] ; then
- echo "WARNING: code-climate-setup: CC_TEST_REPORTER_ID is not set, skipping."
- return
- fi
-
- wget --no-verbose ${CC_CLI_URI}
- chmod +x ${CC_CLI}
-
- export CI_NAME="concourse"
-
- ./${CC_CLI} env
- ./${CC_CLI} before-build
-}
-
-function code-climate-shipit {
- if [ -z "${CC_TEST_REPORTER_ID:-}" ] ; then
- echo "WARNING: code-climate-shipit: CC_TEST_REPORTER_ID is not set, skipping."
- return
- fi
-
- # let's remove the `|| true` once all pull requests from pre-simplecov are cleared out
- ./${CC_CLI} after-build || true
-}
diff --git a/concourse/tasks/gem-test/gem-build-java.sh b/concourse/tasks/gem-test/gem-build-java.sh
deleted file mode 100755
index 2436d719e2..0000000000
--- a/concourse/tasks/gem-test/gem-build-java.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#! /usr/bin/env bash
-
-set -e -x -u
-
-pushd nokogiri
-
- OUTPUT_DIR="../gems"
-
- # inputs from a real git resource will contain this dir, but we may
- # run this task via `fly execute` and so we need to do this to avoid
- # cleanup, see extconf.rb do_clean
- mkdir -p .git
-
- bundle install --local || bundle install
-
- bundle exec rake java gem
-
- mkdir -p ${OUTPUT_DIR}
- cp -v pkg/nokogiri*java.gem ${OUTPUT_DIR}
- sha256sum ${OUTPUT_DIR}/*
-
-popd
diff --git a/concourse/tasks/gem-test/gem-build.sh b/concourse/tasks/gem-test/gem-build.sh
deleted file mode 100755
index f388cead40..0000000000
--- a/concourse/tasks/gem-test/gem-build.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#! /usr/bin/env bash
-
-set -e -x -u
-
-pushd nokogiri
-
- OUTPUT_DIR="../gems"
-
- # inputs from a real git resource will contain this dir, but we may
- # run this task via `fly execute` and so we need to do this to avoid
- # cleanup, see extconf.rb do_clean
- mkdir -p .git
-
- bundle install --local || bundle install
-
- # TODO we're only compiling so that we retrieve libxml2/libxslt
- # tarballs, we can do better a couple of different ways
- bundle exec rake clean compile
- bundle exec rake gem
-
- mkdir -p ${OUTPUT_DIR}
- cp -v pkg/nokogiri*.gem ${OUTPUT_DIR}
- sha256sum ${OUTPUT_DIR}/*
-
-popd
diff --git a/concourse/tasks/gem-test/gem-install-and-test.sh b/concourse/tasks/gem-test/gem-install-and-test.sh
deleted file mode 100755
index 521067c97d..0000000000
--- a/concourse/tasks/gem-test/gem-install-and-test.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#! /usr/bin/env bash
-
-set -e -x -u
-
-pushd gems
-
- gemfile=$(ls *.gem | head -n1)
- sha256sum ${gemfile}
- gem install ${gemfile}
- gem list -d nokogiri
- nokogiri -v
-
-popd
-
-pushd nokogiri
-
- export BUNDLE_GEMFILE=$(pwd)/Gemfile
- bundle -v
- bundle config
-
- bundle add nokogiri --skip-install
- bundle install --local || bundle install
- bundle show nokogiri
-
- bundle exec rake test
-
-popd
diff --git a/concourse/tasks/rake-test/run.ps1 b/concourse/tasks/rake-test/run.ps1
deleted file mode 100644
index 473f3eb725..0000000000
--- a/concourse/tasks/rake-test/run.ps1
+++ /dev/null
@@ -1,11 +0,0 @@
-. "c:\var\vcap\packages\windows-ruby-dev-tools\prelude.ps1"
-
-$env:RUBYOPT = "-rdevkit"
-
-push-location nokogiri
-
- system-cmd "gem install bundler"
- system-cmd "bundle install"
- system-cmd "bundle exec rake compile test"
-
-pop-location
diff --git a/concourse/tasks/rake-test/run.sh b/concourse/tasks/rake-test/run.sh
deleted file mode 100755
index 2a27928d46..0000000000
--- a/concourse/tasks/rake-test/run.sh
+++ /dev/null
@@ -1,60 +0,0 @@
-#! /usr/bin/env bash
-
-set -e -x -u
-
-source "$(dirname "$0")/../../shared/code-climate.sh"
-
-VERSION_INFO=$(ruby -v)
-RUBY_ENGINE=$(cut -d" " -f1 <<< "${VERSION_INFO}")
-RUBY_VERSION=$(cut -d" " -f2 <<< "${VERSION_INFO}")
-
-FROZEN_STRING_REF="53f9b66"
-
-function mri-24-or-greater {
- if [[ $RUBY_ENGINE != "ruby" ]] ; then
- return 1
- fi
-
- if echo $RUBY_VERSION | grep "^[0-2]\.[0-3]\." > /dev/null ; then
- return 1
- fi
-
- return 0
-}
-
-function commit-is-post-frozen-string-support {
- if git merge-base --is-ancestor ${FROZEN_STRING_REF} HEAD ; then
- return 0
- fi
- return 1
-}
-
-pushd nokogiri
-
- test_task="test"
-
- bundle install --local || bundle install
- bundle exec rake generate # do this before setting frozen string option, because racc isn't compatible with frozen string literals yet
-
- if mri-24-or-greater && commit-is-post-frozen-string-support ; then
- export RUBYOPT="--enable-frozen-string-literal --debug=frozen-string-literal"
- fi
-
- if [[ ${TEST_WITH_VALGRIND:-} != "" ]] ; then
- test_task="test:valgrind" # override
- # export TESTOPTS="-v" # see more verbose output to help narrow down warnings
-
- # always use the CI suppressions if they exist
- if [[ -d ../ci/suppressions ]] ; then
- rm -rf suppressions
- cp -var ../ci/suppressions .
- fi
- fi
-
- code-climate-setup
-
- bundle exec rake compile ${test_task}
-
- code-climate-shipit
-
-popd
diff --git a/dependencies.yml b/dependencies.yml
index 533bfd2631..98eccc8984 100644
--- a/dependencies.yml
+++ b/dependencies.yml
@@ -1,72 +1,41 @@
libxml2:
- version: "2.9.9"
- sha256: "94fb70890143e3c6549f265cee93ec064c80a84c42ad0f23e85ee1fd6540a871"
- # manually verified checksum:
- #
- # $ gpg --verify libxml2-2.9.9.tar.gz.asc ports/archives/libxml2-2.9.9.tar.gz
- # gpg: Signature made Thu 03 Jan 2019 01:14:47 PM EST
- # gpg: using RSA key 15588B26596BEA5D
- # gpg: Good signature from "Daniel Veillard (Red Hat work email) " [unknown]
- # gpg: aka "Daniel Veillard " [unknown]
- # gpg: WARNING: This key is not certified with a trusted signature!
- # gpg: There is no indication that the signature belongs to the owner.
- # Primary key fingerprint: C744 15BA 7C9C 7F78 F02E 1DC3 4606 B8A5 DE95 BC1F
- # Subkey fingerprint: DB46 681B B91A DCEA 170F A2D4 1558 8B26 596B EA5D
- #
- # using this pgp signature:
- #
- # -----BEGIN PGP SIGNATURE-----
- #
- # iQEbBAABAgAGBQJcLlEXAAoJEBVYiyZZa+pd1B8H93xeCYNBLx+eX0xe3qS3ReS/
- # YstjkXKUkmDQYwqQ/9Knmv1P6NX64hQL5E1pZX5sXp36giwXXJ5tCK72VRzektzU
- # Kpo+M1/QA9feZQs1GmyKaXYzNwTSJnsdKA9nWqTHZ3bzfdhFSZ0czo94vgY/cz5z
- # 9P3FIgeldj1vi8p2rjXbArMFQyaxHnve9LdxI8hbudNSeUw/FEV6mjtXrlZ7MXqn
- # hmAkah2JwktOStF5tIlddCRqZeUPUX5flBxT95gfskXXlGEhaoGMXcC3izqqJyV2
- # sx5nY7fnXdkwfYsgRUXYWmDmbs8DnFjXH9lux9O4OWglLonaRoAqFPcOzE3aCw==
- # =4qWg
- # -----END PGP SIGNATURE-----
- #
+ version: "2.10.3"
+ sha256: "5d2cc3d78bec3dbe212a9d7fa629ada25a7da928af432c93060ff5c17ee28a9c"
+ # sha-256 hash provided in https://download.gnome.org/sources/libxml2/2.10/libxml2-2.10.3.sha256sum
libxslt:
- version: "1.1.33"
- sha256: "8e36605144409df979cab43d835002f63988f3dc94d5d3537c12796db90e38c8"
- # manually verified checksum:
- #
- # $ gpg --verify libxslt-1.1.33.tar.gz.asc ports/archives/libxslt-1.1.33.tar.gz
- # gpg: Signature made Thu 03 Jan 2019 01:30:49 PM EST
- # gpg: using RSA key 15588B26596BEA5D
- # gpg: Good signature from "Daniel Veillard (Red Hat work email) " [unknown]
- # gpg: aka "Daniel Veillard " [unknown]
- # gpg: WARNING: This key is not certified with a trusted signature!
- # gpg: There is no indication that the signature belongs to the owner.
- # Primary key fingerprint: C744 15BA 7C9C 7F78 F02E 1DC3 4606 B8A5 DE95 BC1F
- # Subkey fingerprint: DB46 681B B91A DCEA 170F A2D4 1558 8B26 596B EA5D
- #
- # using this pgp signature:
- #
- # -----BEGIN PGP SIGNATURE-----
- #
- # iQEcBAABAgAGBQJcLlTZAAoJEBVYiyZZa+pd9NkIAIf6ei2iSpR/0QOyS71esDq8
- # 407PcUXd/yUjDANm4Uvm7kKK+SbbfBxFIPva4g984Noe1zYMfjK3u3iNs6jykySf
- # mN5eo2wNCxsZnqjbnsLgQvn5VCQpPInTddTuGUxgqJyvnR7p785L1oA2EStSPMP4
- # BGZ9dZGlbreK35WzgrhUi0VN5egJW2fpMsw7rTPvfwK+90gXL0DEm8v3WlA7fCDL
- # QsvuPm7jPOXxdt5bYrVP8wpNMTJIGqV6jxh7Vvl6kiGLldUjCyoCh0AGXLror0Gs
- # sAMlRKJNodpcCYkIWxzjLt74sUciKNrPLHZlXJcclZMONen1GWnVDcv83Tt9n6w=
- # =iAm8
- # -----END PGP SIGNATURE-----
- #
+ version: "1.1.37"
+ sha256: "3a4b27dc8027ccd6146725950336f1ec520928f320f144eb5fa7990ae6123ab4"
+ # sha-256 hash provided in https://download.gnome.org/sources/libxslt/1.1/libxslt-1.1.37.sha256sum
zlib:
- version: "1.2.11"
- sha256: "c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1"
+ version: "1.2.13"
+ sha256: "b3a24de97a8fdbc835b9833169501030b8977031bcb54b3b3ac13740f846ab30"
# SHA-256 hash provided on http://zlib.net/
libiconv:
- version: "1.15"
- sha256: "ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178"
- # gpg: Signature made Fri Feb 3 00:38:12 2017 CET
- # gpg: using RSA key 4F494A942E4616C2
- # gpg: Good signature from "Bruno Haible (Open Source Development) " [unknown]
- # gpg: WARNING: This key is not certified with a trusted signature!
- # gpg: There is no indication that the signature belongs to the owner.
- # Primary key fingerprint: 68D9 4D8A AEEA D48A E7DC 5B90 4F49 4A94 2E46 16C2
+ version: "1.17"
+ sha256: "8f74213b56238c85a50a5329f77e06198771e70dd9a739779f4c02f65d971313"
+ # signature verified by following this path:
+ # - release announced at https://savannah.gnu.org/forum/forum.php?forum_id=10175
+ # - which links to https://savannah.gnu.org/users/haible as the releaser
+ # - which links to https://savannah.gnu.org/people/viewgpg.php?user_id=1871 as the gpg key
+ #
+ # So:
+ # - wget -q -O - https://savannah.gnu.org/people/viewgpg.php?user_id=1871 | gpg --import
+ # gpg: key F5BE8B267C6A406D: 1 signature not checked due to a missing key
+ # gpg: key F5BE8B267C6A406D: public key "Bruno Haible (Open Source Development) " imported
+ # gpg: Total number processed: 1
+ # gpg: imported: 1
+ # gpg: marginals needed: 3 completes needed: 1 trust model: pgp
+ # gpg: depth: 0 valid: 4 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 4u
+ # gpg: next trustdb check due at 2024-05-09
+ # - gpg --verify libiconv-1.17.tar.gz.sig ports/archives/libiconv-1.17.tar.gz
+ # gpg: Signature made Sun 15 May 2022 11:26:42 AM EDT
+ # gpg: using RSA key 9001B85AF9E1B83DF1BDA942F5BE8B267C6A406D
+ # gpg: Good signature from "Bruno Haible (Open Source Development) " [unknown]
+ # gpg: WARNING: This key is not certified with a trusted signature!
+ # gpg: There is no indication that the signature belongs to the owner.
+ # Primary key fingerprint: 9001 B85A F9E1 B83D F1BD A942 F5BE 8B26 7C6A 406D
+ #
+ # And this sha256sum is calculated from that verified tarball.
diff --git a/ext/java/nokogiri/EncodingHandler.java b/ext/java/nokogiri/EncodingHandler.java
deleted file mode 100644
index 4adce465b3..0000000000
--- a/ext/java/nokogiri/EncodingHandler.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * (The MIT License)
- *
- * Copyright (c) 2008 - 2011:
- *
- * * {Aaron Patterson}[http://tenderlovemaking.com]
- * * {Mike Dalessio}[http://mike.daless.io]
- * * {Charles Nutter}[http://blog.headius.com]
- * * {Sergio Arbeo}[http://www.serabe.com]
- * * {Patrick Mahoney}[http://polycrystal.org]
- * * {Yoko Harada}[http://yokolet.blogspot.com]
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * 'Software'), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-package nokogiri;
-
-import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
-
-import java.util.HashMap;
-
-import org.jruby.Ruby;
-import org.jruby.RubyClass;
-import org.jruby.RubyObject;
-import org.jruby.anno.JRubyClass;
-import org.jruby.anno.JRubyMethod;
-import org.jruby.runtime.ThreadContext;
-import org.jruby.runtime.builtin.IRubyObject;
-
-/**
- * Stub class to satisfy unit tests. I'm not sure where this class is
- * meant to be used. As coded it won't really interact with any other
- * classes and will have no effect on character encodings reported by
- * documents being parsed.
- *
- * @author Patrick Mahoney
- */
-@JRubyClass(name="Nokogiri::EncodingHandler")
-public class EncodingHandler extends RubyObject {
- protected static HashMap map = new HashMap();
- static {
- addInitial();
- }
-
- protected String name;
-
- protected static void addInitial() {
- map.put("UTF-8", "UTF-8");
- }
-
- public EncodingHandler(Ruby ruby, RubyClass klass, String value) {
- super(ruby, klass);
- name = value;
- }
-
- @JRubyMethod(name="[]", meta=true)
- public static IRubyObject get(ThreadContext context,
- IRubyObject _klass,
- IRubyObject keyObj) {
- Ruby ruby = context.getRuntime();
- String key = keyObj.toString();
- String value = map.get(key);
- if (value == null)
- return ruby.getNil();
-
- return new EncodingHandler(
- ruby,
- getNokogiriClass(ruby, "Nokogiri::EncodingHandler"),
- value);
- }
-
- @JRubyMethod(meta=true)
- public static IRubyObject delete(ThreadContext context,
- IRubyObject _klass,
- IRubyObject keyObj) {
- String key = keyObj.toString();
- String value = map.remove(key);
- if (value == null)
- return context.getRuntime().getNil();
- return context.getRuntime().newString(value);
- }
-
- @JRubyMethod(name="clear_aliases!", meta=true)
- public static IRubyObject clear_aliases(ThreadContext context,
- IRubyObject _klass) {
- map.clear();
- addInitial();
- return context.getRuntime().getNil();
- }
-
- @JRubyMethod(meta=true)
- public static IRubyObject alias(ThreadContext context,
- IRubyObject _klass,
- IRubyObject orig,
- IRubyObject alias) {
- String value = map.get(orig.toString());
- if (value != null)
- map.put(alias.toString(), value);
-
- return context.getRuntime().getNil();
- }
-
- @JRubyMethod
- public IRubyObject name(ThreadContext context) {
- return context.getRuntime().newString(name);
- }
-}
diff --git a/ext/java/nokogiri/Html4Document.java b/ext/java/nokogiri/Html4Document.java
new file mode 100644
index 0000000000..b0de1adf1e
--- /dev/null
+++ b/ext/java/nokogiri/Html4Document.java
@@ -0,0 +1,157 @@
+package nokogiri;
+
+import org.jruby.Ruby;
+import org.jruby.RubyClass;
+import org.jruby.anno.JRubyClass;
+import org.jruby.anno.JRubyMethod;
+import org.jruby.runtime.Helpers;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.builtin.IRubyObject;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import nokogiri.internals.HtmlDomParserContext;
+
+import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
+
+/**
+ * Class for Nokogiri::HTML4::Document.
+ *
+ * @author sergio
+ * @author Yoko Harada
+ */
+@JRubyClass(name = "Nokogiri::HTML4::Document", parent = "Nokogiri::XML::Document")
+public class Html4Document extends XmlDocument
+{
+ private static final long serialVersionUID = 1L;
+
+ private static final String DEFAULT_CONTENT_TYPE = "html";
+ private static final String DEFAULT_PUBLIC_ID = "-//W3C//DTD HTML 4.01//EN";
+ private static final String DEFAULT_SYTEM_ID = "http://www.w3.org/TR/html4/strict.dtd";
+
+ private String parsed_encoding = null;
+
+ public
+ Html4Document(Ruby ruby, RubyClass klazz)
+ {
+ super(ruby, klazz);
+ }
+
+ public
+ Html4Document(Ruby runtime, Document document)
+ {
+ this(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Document"), document);
+ }
+
+ public
+ Html4Document(Ruby ruby, RubyClass klazz, Document doc)
+ {
+ super(ruby, klazz, doc);
+ }
+
+ @JRubyMethod(name = "new", meta = true, rest = true, required = 0)
+ public static IRubyObject
+ rbNew(ThreadContext context, IRubyObject klazz, IRubyObject[] args)
+ {
+ final Ruby runtime = context.runtime;
+ Html4Document htmlDocument;
+ try {
+ Document docNode = createNewDocument(runtime);
+ htmlDocument = (Html4Document) NokogiriService.HTML_DOCUMENT_ALLOCATOR.allocate(runtime, (RubyClass) klazz);
+ htmlDocument.setDocumentNode(context.runtime, docNode);
+ } catch (Exception ex) {
+ throw asRuntimeError(runtime, "couldn't create document: ", ex);
+ }
+
+ Helpers.invoke(context, htmlDocument, "initialize", args);
+
+ return htmlDocument;
+ }
+
+ public IRubyObject
+ getInternalSubset(ThreadContext context)
+ {
+ IRubyObject internalSubset = super.getInternalSubset(context);
+
+ // html documents are expected to have a default internal subset
+ // the default values are the same ones used when the following
+ // feature is turned on
+ // "http://cyberneko.org/html/features/insert-doctype"
+ // the reason we don't turn it on, is because it overrides the document's
+ // declared doctype declaration.
+
+ if (internalSubset.isNil()) {
+ internalSubset = XmlDtd.newEmpty(context.getRuntime(),
+ getDocument(),
+ context.getRuntime().newString(DEFAULT_CONTENT_TYPE),
+ context.getRuntime().newString(DEFAULT_PUBLIC_ID),
+ context.getRuntime().newString(DEFAULT_SYTEM_ID));
+ setInternalSubset(internalSubset);
+ }
+
+ return internalSubset;
+ }
+
+ @Override
+ void
+ init(Ruby runtime, Document document)
+ {
+ stabilizeTextContent(document);
+ document.normalize();
+ setInstanceVariable("@decorators", runtime.getNil());
+ if (document.getDocumentElement() != null) {
+ stabilizeAttrs(document.getDocumentElement());
+ }
+ }
+
+ private static void
+ stabilizeAttrs(Node node)
+ {
+ if (node.hasAttributes()) {
+ NamedNodeMap nodeMap = node.getAttributes();
+ for (int i = 0; i < nodeMap.getLength(); i++) {
+ Node n = nodeMap.item(i);
+ if (n instanceof Attr) {
+ stabilizeAttr((Attr) n);
+ }
+ }
+ }
+ NodeList children = node.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ stabilizeAttrs(children.item(i));
+ }
+ }
+
+ public void
+ setParsedEncoding(String encoding)
+ {
+ parsed_encoding = encoding;
+ }
+
+ public String
+ getPraedEncoding()
+ {
+ return parsed_encoding;
+ }
+
+ @JRubyMethod(meta = true, required = 4)
+ public static IRubyObject
+ read_io(ThreadContext context, IRubyObject klass, IRubyObject[] args)
+ {
+ HtmlDomParserContext ctx = new HtmlDomParserContext(context.runtime, args[2], args[3]);
+ ctx.setIOInputSource(context, args[0], args[1]);
+ return ctx.parse(context, (RubyClass) klass, args[1]);
+ }
+
+ @JRubyMethod(meta = true, required = 4)
+ public static IRubyObject
+ read_memory(ThreadContext context, IRubyObject klass, IRubyObject[] args)
+ {
+ HtmlDomParserContext ctx = new HtmlDomParserContext(context.runtime, args[2], args[3]);
+ ctx.setStringInputSource(context, args[0], args[1]);
+ return ctx.parse(context, (RubyClass) klass, args[1]);
+ }
+}
diff --git a/ext/java/nokogiri/Html4ElementDescription.java b/ext/java/nokogiri/Html4ElementDescription.java
new file mode 100644
index 0000000000..8613245914
--- /dev/null
+++ b/ext/java/nokogiri/Html4ElementDescription.java
@@ -0,0 +1,133 @@
+package nokogiri;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.htmlunit.cyberneko.HTMLElements;
+import org.jruby.Ruby;
+import org.jruby.RubyClass;
+import org.jruby.RubyObject;
+import org.jruby.anno.JRubyClass;
+import org.jruby.anno.JRubyMethod;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.builtin.IRubyObject;
+
+/**
+ * Class for Nokogiri::HTML4::ElementDescription.
+ *
+ * @author Patrick Mahoney
+ */
+@JRubyClass(name = "Nokogiri::HTML4::ElementDescription")
+public class Html4ElementDescription extends RubyObject
+{
+ private static final long serialVersionUID = 1L;
+ private static final HTMLElements htmlElements_ = new HTMLElements();
+
+ /**
+ * Stores memoized hash of element -> list of valid subelements.
+ */
+ static protected Map> subElements;
+ static
+ {
+ Map> _subElements =
+ new HashMap>();
+ subElements = Collections.synchronizedMap(_subElements);
+ }
+
+ protected HTMLElements.Element element;
+
+ public
+ Html4ElementDescription(Ruby runtime, RubyClass rubyClass)
+ {
+ super(runtime, rubyClass);
+ }
+
+ /**
+ * Lookup the list of sub elements of code. If not
+ * already stored, iterate through all elements to find valid
+ * subelements; save this list and return it.
+ */
+ protected static List
+ findSubElements(HTMLElements.Element elem)
+ {
+ List subs = subElements.get(elem.code);
+
+ if (subs == null) {
+ subs = new ArrayList();
+
+ /*
+ * A bit of a hack. NekoHtml source code shows that
+ * UNKNOWN is the highest value element. We cannot access
+ * the list of elements directly because it's protected.
+ */
+ for (short c = 0; c < HTMLElements.UNKNOWN; c++) {
+ HTMLElements.Element maybe_sub = htmlElements_.getElement(c);
+ if (maybe_sub != null && maybe_sub.isParent(elem)) {
+ subs.add(maybe_sub.name);
+ }
+ }
+
+ subElements.put(elem.code, subs);
+ }
+
+ return subs;
+ }
+
+ @JRubyMethod(name = "[]", meta = true)
+ public static IRubyObject
+ get(ThreadContext context,
+ IRubyObject klazz, IRubyObject name)
+ {
+
+ // nekohtml will return an element even for invalid names, which breaks `test_fetch_nonexistent'
+ // see getElement() in HTMLElements.java
+ HTMLElements.Element elem = htmlElements_.getElement(name.asJavaString(), htmlElements_.NO_SUCH_ELEMENT);
+ if (elem == htmlElements_.NO_SUCH_ELEMENT) {
+ return context.nil;
+ }
+
+ Html4ElementDescription desc =
+ new Html4ElementDescription(context.getRuntime(), (RubyClass)klazz);
+ desc.element = elem;
+ return desc;
+ }
+
+ @JRubyMethod()
+ public IRubyObject
+ name(ThreadContext context)
+ {
+ return context.getRuntime().newString(element.name.toLowerCase());
+ }
+
+ @JRubyMethod(name = "inline?")
+ public IRubyObject
+ inline_eh(ThreadContext context)
+ {
+ return context.getRuntime().newBoolean(element.isInline());
+ }
+
+ @JRubyMethod(name = "empty?")
+ public IRubyObject
+ empty_eh(ThreadContext context)
+ {
+ return context.getRuntime().newBoolean(element.isEmpty());
+ }
+
+ @JRubyMethod()
+ public IRubyObject
+ sub_elements(ThreadContext context)
+ {
+ Ruby ruby = context.getRuntime();
+ List subs = findSubElements(element);
+ IRubyObject[] ary = new IRubyObject[subs.size()];
+ for (int i = 0; i < subs.size(); ++i) {
+ ary[i] = ruby.newString(subs.get(i));
+ }
+
+ return ruby.newArray(ary);
+ }
+
+}
diff --git a/ext/java/nokogiri/Html4EntityLookup.java b/ext/java/nokogiri/Html4EntityLookup.java
new file mode 100644
index 0000000000..5d98f1f8c9
--- /dev/null
+++ b/ext/java/nokogiri/Html4EntityLookup.java
@@ -0,0 +1,63 @@
+package nokogiri;
+
+import static org.jruby.runtime.Helpers.invoke;
+
+import net.sourceforge.htmlunit.cyberneko.HTMLEntitiesParser;
+import org.jruby.Ruby;
+import org.jruby.RubyClass;
+import org.jruby.RubyObject;
+import org.jruby.anno.JRubyClass;
+import org.jruby.anno.JRubyMethod;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.builtin.IRubyObject;
+
+/**
+ * Class for Nokogiri::HTML4::EntityLookup.
+ *
+ * @author Patrick Mahoney
+ */
+@JRubyClass(name = "Nokogiri::HTML4::EntityLookup")
+public class Html4EntityLookup extends RubyObject
+{
+ private static final long serialVersionUID = 1L;
+
+ public
+ Html4EntityLookup(Ruby runtime, RubyClass rubyClass)
+ {
+ super(runtime, rubyClass);
+ }
+
+ /**
+ * Looks up an HTML entity key.
+ *
+ * The description is a bit lacking.
+ */
+ @JRubyMethod()
+ public IRubyObject
+ get(ThreadContext context, IRubyObject key)
+ {
+ Ruby ruby = context.getRuntime();
+ String name = key.toString();
+
+ HTMLEntitiesParser parser = new HTMLEntitiesParser();
+ for (int j = 0 ; j < name.length() ; j++) {
+ if (!parser.parse(name.charAt(j))) {
+ break;
+ }
+ }
+ String match = parser.getMatch();
+
+ if (match == null) { return ruby.getNil(); }
+
+ int val = match.charAt(0);
+
+ IRubyObject edClass =
+ ruby.getClassFromPath("Nokogiri::HTML4::EntityDescription");
+ IRubyObject edObj = invoke(context, edClass, "new",
+ ruby.newFixnum(val), ruby.newString(name),
+ ruby.newString(name + " entity"));
+
+ return edObj;
+ }
+
+}
diff --git a/ext/java/nokogiri/Html4SaxParserContext.java b/ext/java/nokogiri/Html4SaxParserContext.java
new file mode 100644
index 0000000000..ed34e5b313
--- /dev/null
+++ b/ext/java/nokogiri/Html4SaxParserContext.java
@@ -0,0 +1,289 @@
+package nokogiri;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.xerces.parsers.AbstractSAXParser;
+import net.sourceforge.htmlunit.cyberneko.parsers.SAXParser;
+import org.jruby.Ruby;
+import org.jruby.RubyClass;
+import org.jruby.RubyFixnum;
+import org.jruby.RubyString;
+import org.jruby.anno.JRubyClass;
+import org.jruby.anno.JRubyMethod;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.builtin.IRubyObject;
+import org.xml.sax.SAXException;
+
+import nokogiri.internals.NokogiriHandler;
+import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
+
+/**
+ * Class for Nokogiri::HTML4::SAX::ParserContext.
+ *
+ * @author serabe
+ * @author Patrick Mahoney
+ * @author Yoko Harada
+ */
+@JRubyClass(name = "Nokogiri::HTML4::SAX::ParserContext", parent = "Nokogiri::XML::SAX::ParserContext")
+public class Html4SaxParserContext extends XmlSaxParserContext
+{
+ private static final long serialVersionUID = 1L;
+
+ static Html4SaxParserContext
+ newInstance(final Ruby runtime, final RubyClass klazz)
+ {
+ Html4SaxParserContext instance = new Html4SaxParserContext(runtime, klazz);
+ instance.initialize(runtime);
+ return instance;
+ }
+
+ public
+ Html4SaxParserContext(Ruby ruby, RubyClass rubyClass)
+ {
+ super(ruby, rubyClass);
+ }
+
+ @Override
+ protected AbstractSAXParser
+ createParser() throws SAXException
+ {
+ SAXParser parser = new SAXParser();
+
+ try {
+ parser.setProperty(
+ "http://cyberneko.org/html/properties/names/elems", "lower");
+ parser.setProperty(
+ "http://cyberneko.org/html/properties/names/attrs", "lower");
+
+ // NekoHTML should not try to guess the encoding based on the meta
+ // tags or other information in the document. This is already
+ // handled by the EncodingReader.
+ parser.setFeature("http://cyberneko.org/html/features/scanner/ignore-specified-charset", true);
+ return parser;
+ } catch (SAXException ex) {
+ throw new SAXException(
+ "Problem while creating HTML4 SAX Parser: " + ex.toString());
+ }
+ }
+
+ @JRubyMethod(name = "memory", meta = true)
+ public static IRubyObject
+ parse_memory(ThreadContext context,
+ IRubyObject klazz,
+ IRubyObject data,
+ IRubyObject encoding)
+ {
+ Html4SaxParserContext ctx = Html4SaxParserContext.newInstance(context.runtime, (RubyClass) klazz);
+ String javaEncoding = findEncodingName(context, encoding);
+ if (javaEncoding != null) {
+ CharSequence input = applyEncoding(rubyStringToString(data.convertToString()), javaEncoding);
+ ByteArrayInputStream istream = new ByteArrayInputStream(input.toString().getBytes());
+ ctx.setInputSource(istream);
+ ctx.getInputSource().setEncoding(javaEncoding);
+ }
+ return ctx;
+ }
+
+ public enum EncodingType {
+ NONE(0, "NONE"),
+ UTF_8(1, "UTF-8"),
+ UTF16LE(2, "UTF16LE"),
+ UTF16BE(3, "UTF16BE"),
+ UCS4LE(4, "UCS4LE"),
+ UCS4BE(5, "UCS4BE"),
+ EBCDIC(6, "EBCDIC"),
+ UCS4_2143(7, "ICS4-2143"),
+ UCS4_3412(8, "UCS4-3412"),
+ UCS2(9, "UCS2"),
+ ISO_8859_1(10, "ISO-8859-1"),
+ ISO_8859_2(11, "ISO-8859-2"),
+ ISO_8859_3(12, "ISO-8859-3"),
+ ISO_8859_4(13, "ISO-8859-4"),
+ ISO_8859_5(14, "ISO-8859-5"),
+ ISO_8859_6(15, "ISO-8859-6"),
+ ISO_8859_7(16, "ISO-8859-7"),
+ ISO_8859_8(17, "ISO-8859-8"),
+ ISO_8859_9(18, "ISO-8859-9"),
+ ISO_2022_JP(19, "ISO-2022-JP"),
+ SHIFT_JIS(20, "SHIFT-JIS"),
+ EUC_JP(21, "EUC-JP"),
+ ASCII(22, "ASCII");
+
+ private final int value;
+ private final String name;
+
+ EncodingType(int value, String name)
+ {
+ this.value = value;
+ this.name = name;
+ }
+
+ public int getValue()
+ {
+ return value;
+ }
+
+ public String toString()
+ {
+ return name;
+ }
+
+ private static transient EncodingType[] values;
+
+ // NOTE: assuming ordinal == value
+ static EncodingType get(final int ordinal)
+ {
+ EncodingType[] values = EncodingType.values;
+ if (values == null) {
+ values = EncodingType.values();
+ EncodingType.values = values;
+ }
+ if (ordinal >= 0 && ordinal < values.length) {
+ return values[ordinal];
+ }
+ return null;
+ }
+
+ }
+
+ private static String
+ findEncodingName(final int value)
+ {
+ EncodingType type = EncodingType.get(value);
+ if (type == null) { return null; }
+ assert type.value == value;
+ return type.name;
+ }
+
+ private static String
+ findEncodingName(ThreadContext context, IRubyObject encoding)
+ {
+ String rubyEncoding = null;
+ if (encoding instanceof RubyString) {
+ rubyEncoding = rubyStringToString((RubyString) encoding);
+ } else if (encoding instanceof RubyFixnum) {
+ rubyEncoding = findEncodingName(RubyFixnum.fix2int((RubyFixnum) encoding));
+ }
+ if (rubyEncoding == null) { return null; }
+ try {
+ return Charset.forName(rubyEncoding).displayName();
+ } catch (UnsupportedCharsetException e) {
+ throw context.getRuntime().newEncodingCompatibilityError(rubyEncoding + "is not supported");
+ } catch (IllegalCharsetNameException e) {
+ throw context.getRuntime().newEncodingError(e.getMessage());
+ }
+ }
+
+ private static final Pattern CHARSET_PATTERN = Pattern.compile("charset(()|\\s)=(()|\\s)([a-z]|-|_|\\d)+",
+ Pattern.CASE_INSENSITIVE);
+
+ private static CharSequence
+ applyEncoding(final String input, final String enc)
+ {
+ int start_pos = 0;
+ int end_pos = 0;
+ if (containsIgnoreCase(input, "charset")) {
+ Matcher m = CHARSET_PATTERN.matcher(input);
+ while (m.find()) {
+ start_pos = m.start();
+ end_pos = m.end();
+ }
+ }
+ if (start_pos != end_pos) {
+ return new StringBuilder(input).replace(start_pos, end_pos, "charset=" + enc);
+ }
+ return input;
+ }
+
+ private static boolean
+ containsIgnoreCase(final String str, final String sub)
+ {
+ final int len = sub.length();
+ final int max = str.length() - len;
+
+ if (len == 0) { return true; }
+ final char c0Lower = Character.toLowerCase(sub.charAt(0));
+ final char c0Upper = Character.toUpperCase(sub.charAt(0));
+
+ for (int i = 0; i <= max; i++) {
+ final char ch = str.charAt(i);
+ if (ch != c0Lower && Character.toLowerCase(ch) != c0Lower && Character.toUpperCase(ch) != c0Upper) {
+ continue; // first char doesn't match
+ }
+
+ if (str.regionMatches(true, i + 1, sub, 0 + 1, len - 1)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @JRubyMethod(name = "file", meta = true)
+ public static IRubyObject
+ parse_file(ThreadContext context,
+ IRubyObject klass,
+ IRubyObject data,
+ IRubyObject encoding)
+ {
+ if (!(data instanceof RubyString)) {
+ throw context.getRuntime().newTypeError("data must be kind_of String");
+ }
+ if (!(encoding instanceof RubyString)) {
+ throw context.getRuntime().newTypeError("data must be kind_of String");
+ }
+
+ Html4SaxParserContext ctx = Html4SaxParserContext.newInstance(context.runtime, (RubyClass) klass);
+ ctx.setInputSourceFile(context, data);
+ String javaEncoding = findEncodingName(context, encoding);
+ if (javaEncoding != null) {
+ ctx.getInputSource().setEncoding(javaEncoding);
+ }
+ return ctx;
+ }
+
+ @JRubyMethod(name = "io", meta = true)
+ public static IRubyObject
+ parse_io(ThreadContext context,
+ IRubyObject klass,
+ IRubyObject data,
+ IRubyObject encoding)
+ {
+ if (!(encoding instanceof RubyFixnum)) {
+ throw context.getRuntime().newTypeError("encoding must be kind_of String");
+ }
+
+ Html4SaxParserContext ctx = Html4SaxParserContext.newInstance(context.runtime, (RubyClass) klass);
+ ctx.setIOInputSource(context, data, context.nil);
+ String javaEncoding = findEncodingName(context, encoding);
+ if (javaEncoding != null) {
+ ctx.getInputSource().setEncoding(javaEncoding);
+ }
+ return ctx;
+ }
+
+ /**
+ * Create a new parser context that will read from a raw input stream.
+ * Meant to be run in a separate thread by Html4SaxPushParser.
+ */
+ static Html4SaxParserContext
+ parse_stream(final Ruby runtime, RubyClass klass, InputStream stream)
+ {
+ Html4SaxParserContext ctx = Html4SaxParserContext.newInstance(runtime, klass);
+ ctx.setInputSource(stream);
+ return ctx;
+ }
+
+ @Override
+ protected void
+ preParse(final Ruby runtime, IRubyObject handlerRuby, NokogiriHandler handler)
+ {
+ // this function is meant to be empty. It overrides the one in XmlSaxParserContext
+ }
+
+}
diff --git a/ext/java/nokogiri/Html4SaxPushParser.java b/ext/java/nokogiri/Html4SaxPushParser.java
new file mode 100644
index 0000000000..c338fd3696
--- /dev/null
+++ b/ext/java/nokogiri/Html4SaxPushParser.java
@@ -0,0 +1,213 @@
+package nokogiri;
+
+import nokogiri.internals.ClosedStreamException;
+import nokogiri.internals.NokogiriBlockingQueueInputStream;
+import nokogiri.internals.NokogiriHelpers;
+import nokogiri.internals.ParserContext;
+import org.jruby.Ruby;
+import org.jruby.RubyClass;
+import org.jruby.RubyObject;
+import org.jruby.anno.JRubyClass;
+import org.jruby.anno.JRubyMethod;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.builtin.IRubyObject;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.*;
+
+import static nokogiri.XmlSaxPushParser.terminateExecution;
+import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
+import static org.jruby.runtime.Helpers.invoke;
+
+/**
+ * Class for Nokogiri::HTML4::SAX::PushParser
+ *
+ * @author
+ * @author Piotr Szmielew - based on Nokogiri::XML::SAX::PushParser
+ */
+@JRubyClass(name = "Nokogiri::HTML4::SAX::PushParser")
+public class Html4SaxPushParser extends RubyObject
+{
+ private static final long serialVersionUID = 1L;
+
+ ParserContext.Options options;
+ IRubyObject saxParser;
+
+ NokogiriBlockingQueueInputStream stream;
+
+ private ParserTask parserTask = null;
+ private FutureTask futureTask = null;
+ private ExecutorService executor = null;
+
+ public
+ Html4SaxPushParser(Ruby ruby, RubyClass rubyClass)
+ {
+ super(ruby, rubyClass);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void
+ finalize()
+ {
+ try {
+ terminateImpl();
+ } catch (Exception e) { /* ignored */ }
+ }
+
+ @JRubyMethod
+ public IRubyObject
+ initialize_native(final ThreadContext context,
+ IRubyObject saxParser,
+ IRubyObject fileName,
+ IRubyObject encoding)
+ {
+ // NOTE: Silently skips provided encoding
+ options = new ParserContext.Options(0);
+ this.saxParser = saxParser;
+ return this;
+ }
+
+ private transient IRubyObject parse_options;
+
+ private IRubyObject
+ parse_options(final ThreadContext context)
+ {
+ if (parse_options == null) {
+ parse_options = invoke(context, context.runtime.getClassFromPath("Nokogiri::XML::ParseOptions"), "new");
+ }
+ return parse_options;
+ }
+
+ @JRubyMethod(name = "options")
+ public IRubyObject
+ getOptions(ThreadContext context)
+ {
+ return invoke(context, parse_options(context), "options");
+ }
+
+ @JRubyMethod(name = "options=")
+ public IRubyObject
+ setOptions(ThreadContext context, IRubyObject opts)
+ {
+ invoke(context, parse_options(context), "options=", opts);
+ options = new ParserContext.Options(opts.convertToInteger().getLongValue());
+ return getOptions(context);
+ }
+
+ @JRubyMethod
+ public IRubyObject
+ native_write(ThreadContext context, IRubyObject chunk, IRubyObject isLast)
+ {
+ try {
+ initialize_task(context);
+ } catch (IOException e) {
+ throw context.getRuntime().newRuntimeError(e.getMessage());
+ }
+ final ByteArrayInputStream data = NokogiriHelpers.stringBytesToStream(chunk);
+ if (data == null) {
+ terminateTask(context.runtime);
+ throw XmlSyntaxError.createHTMLSyntaxError(context.runtime).toThrowable(); // Nokogiri::HTML4::SyntaxError
+ }
+
+ int errorCount0 = parserTask.getErrorCount();
+
+ if (isLast.isTrue()) {
+ IRubyObject document = invoke(context, this, "document");
+ invoke(context, document, "end_document");
+ terminateTask(context.runtime);
+ } else {
+ try {
+ Future task = stream.addChunk(data);
+ task.get();
+ } catch (ClosedStreamException ex) {
+ // this means the stream is closed, ignore this exception
+ } catch (Exception e) {
+ throw context.runtime.newRuntimeError(e.getMessage());
+ }
+
+ }
+
+ if (!options.recover && parserTask.getErrorCount() > errorCount0) {
+ terminateTask(context.runtime);
+ throw parserTask.getLastError().toThrowable();
+ }
+
+ return this;
+ }
+
+ @SuppressWarnings("unchecked")
+ private void
+ initialize_task(ThreadContext context) throws IOException
+ {
+ if (futureTask == null || stream == null) {
+ stream = new NokogiriBlockingQueueInputStream();
+
+ assert saxParser != null : "saxParser null";
+ parserTask = new ParserTask(context, saxParser, stream);
+ futureTask = new FutureTask((Callable) parserTask);
+ executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r);
+ t.setName("Html4SaxPushParser");
+ t.setDaemon(true);
+ return t;
+ }
+ });
+ executor.submit(futureTask);
+ }
+ }
+
+ private void
+ terminateTask(final Ruby runtime)
+ {
+ if (executor == null) { return; }
+
+ try {
+ terminateImpl();
+ } catch (InterruptedException e) {
+ throw runtime.newRuntimeError(e.toString());
+ } catch (Exception e) {
+ throw runtime.newRuntimeError(e.toString());
+ }
+ }
+
+ private synchronized void
+ terminateImpl() throws InterruptedException, ExecutionException
+ {
+ terminateExecution(executor, stream, futureTask);
+
+ executor = null;
+ stream = null;
+ futureTask = null;
+ }
+
+ private static Html4SaxParserContext
+ parse(final Ruby runtime, final InputStream stream)
+ {
+ RubyClass klazz = getNokogiriClass(runtime, "Nokogiri::HTML4::SAX::ParserContext");
+ return Html4SaxParserContext.parse_stream(runtime, klazz, stream);
+ }
+
+ static class ParserTask extends XmlSaxPushParser.ParserTask /* */
+ {
+
+ private
+ ParserTask(ThreadContext context, IRubyObject handler, InputStream stream)
+ {
+ super(context, handler, parse(context.runtime, stream), stream);
+ }
+
+ @Override
+ public Html4SaxParserContext
+ call() throws Exception
+ {
+ return (Html4SaxParserContext) super.call();
+ }
+
+ }
+
+}
diff --git a/ext/java/nokogiri/HtmlDocument.java b/ext/java/nokogiri/HtmlDocument.java
deleted file mode 100644
index ff5245434f..0000000000
--- a/ext/java/nokogiri/HtmlDocument.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/**
- * (The MIT License)
- *
- * Copyright (c) 2008 - 2012:
- *
- * * {Aaron Patterson}[http://tenderlovemaking.com]
- * * {Mike Dalessio}[http://mike.daless.io]
- * * {Charles Nutter}[http://blog.headius.com]
- * * {Sergio Arbeo}[http://www.serabe.com]
- * * {Patrick Mahoney}[http://polycrystal.org]
- * * {Yoko Harada}[http://yokolet.blogspot.com]
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * 'Software'), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-package nokogiri;
-
-import org.jruby.Ruby;
-import org.jruby.RubyClass;
-import org.jruby.anno.JRubyClass;
-import org.jruby.anno.JRubyMethod;
-import org.jruby.runtime.Arity;
-import org.jruby.runtime.Helpers;
-import org.jruby.runtime.ThreadContext;
-import org.jruby.runtime.builtin.IRubyObject;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import nokogiri.internals.HtmlDomParserContext;
-
-/**
- * Class for Nokogiri::HTML::Document.
- *
- * @author sergio
- * @author Yoko Harada
- */
-@JRubyClass(name="Nokogiri::HTML::Document", parent="Nokogiri::XML::Document")
-public class HtmlDocument extends XmlDocument {
- private static final String DEFAULT_CONTENT_TYPE = "html";
- private static final String DEFAULT_PUBLIC_ID = "-//W3C//DTD HTML 4.01//EN";
- private static final String DEFAULT_SYTEM_ID = "http://www.w3.org/TR/html4/strict.dtd";
-
- private String parsed_encoding = null;
-
- public HtmlDocument(Ruby ruby, RubyClass klazz) {
- super(ruby, klazz);
- }
-
- public HtmlDocument(Ruby ruby, RubyClass klazz, Document doc) {
- super(ruby, klazz, doc);
- }
-
- @JRubyMethod(name="new", meta = true, rest = true, required=0)
- public static IRubyObject rbNew(ThreadContext context, IRubyObject klazz,
- IRubyObject[] args) {
- HtmlDocument htmlDocument;
- try {
- Document docNode = createNewDocument();
- htmlDocument = (HtmlDocument) NokogiriService.HTML_DOCUMENT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass) klazz);
- htmlDocument.setDocumentNode(context, docNode);
- } catch (Exception ex) {
- throw context.getRuntime().newRuntimeError("couldn't create document: " + ex);
- }
-
- Helpers.invoke(context, htmlDocument, "initialize", args);
-
- return htmlDocument;
- }
-
- public IRubyObject getInternalSubset(ThreadContext context) {
- IRubyObject internalSubset = super.getInternalSubset(context);
-
- // html documents are expected to have a default internal subset
- // the default values are the same ones used when the following
- // feature is turned on
- // "http://cyberneko.org/html/features/insert-doctype"
- // the reason we don't turn it on, is because it overrides the document's
- // declared doctype declaration.
-
- if (internalSubset.isNil()) {
- internalSubset = XmlDtd.newEmpty(context.getRuntime(),
- getDocument(),
- context.getRuntime().newString(DEFAULT_CONTENT_TYPE),
- context.getRuntime().newString(DEFAULT_PUBLIC_ID),
- context.getRuntime().newString(DEFAULT_SYTEM_ID));
- setInternalSubset(internalSubset);
- }
-
- return internalSubset;
- }
-
- public static IRubyObject do_parse(ThreadContext context,
- IRubyObject klass,
- IRubyObject[] args) {
- Ruby ruby = context.getRuntime();
- Arity.checkArgumentCount(ruby, args, 4, 4);
- HtmlDomParserContext ctx =
- new HtmlDomParserContext(ruby, args[2], args[3]);
- ctx.setInputSource(context, args[0], args[1]);
- return ctx.parse(context, klass, args[1]);
- }
-
- public void setDocumentNode(ThreadContext context, Node node) {
- super.setNode(context, node);
- Ruby runtime = context.getRuntime();
- if (node != null) {
- Document document = (Document)node;
- document.normalize();
- stabilzeAttrValue(document.getDocumentElement());
- }
- setInstanceVariable("@decorators", runtime.getNil());
- }
-
- private void stabilzeAttrValue(Node node) {
- if (node == null) return;
- if (node.hasAttributes()) {
- NamedNodeMap nodeMap = node.getAttributes();
- for (int i=0; i
- */
-@JRubyClass(name="Nokogiri::HTML::ElementDescription")
-public class HtmlElementDescription extends RubyObject {
-
- /**
- * Stores memoized hash of element -> list of valid subelements.
- */
- static protected Map> subElements;
- static {
- Map> _subElements =
- new HashMap>();
- subElements = Collections.synchronizedMap(_subElements);
- }
-
- protected HTMLElements.Element element;
-
- public HtmlElementDescription(Ruby runtime, RubyClass rubyClass) {
- super(runtime, rubyClass);
- }
-
- /**
- * Lookup the list of sub elements of code. If not
- * already stored, iterate through all elements to find valid
- * subelements; save this list and return it.
- */
- protected static List findSubElements(HTMLElements.Element elem) {
- List subs = subElements.get(elem.code);
-
- if (subs == null) {
- subs = new ArrayList();
-
- /*
- * A bit of a hack. NekoHtml source code shows that
- * UNKNOWN is the highest value element. We cannot access
- * the list of elements directly because it's protected.
- */
- for (short c = 0; c < HTMLElements.UNKNOWN; c++) {
- HTMLElements.Element maybe_sub =
- HTMLElements.getElement(c);
- if (maybe_sub.isParent(elem)) {
- subs.add(maybe_sub.name);
- }
- }
-
- subElements.put(elem.code, subs);
- }
-
- return subs;
- }
-
- @JRubyMethod(name="[]", meta=true)
- public static IRubyObject get(ThreadContext context,
- IRubyObject klazz, IRubyObject name) {
-
- // nekohtml will return an element even for invalid names, see
- // http://sourceforge.net/p/nekohtml/code/HEAD/tree/trunk/src/org/cyberneko/html/HTMLElements.java#l514
- // which breaks `test_fetch_nonexistent'
- HTMLElements.Element elem = HTMLElements.getElement(name.asJavaString(), HTMLElements.NO_SUCH_ELEMENT);
- if (elem == HTMLElements.NO_SUCH_ELEMENT)
- return context.nil;
-
- HtmlElementDescription desc =
- new HtmlElementDescription(context.getRuntime(), (RubyClass)klazz);
- desc.element = elem;
- return desc;
- }
-
- @JRubyMethod()
- public IRubyObject name(ThreadContext context) {
- return context.getRuntime().newString(element.name.toLowerCase());
- }
-
- @JRubyMethod(name="inline?")
- public IRubyObject inline_eh(ThreadContext context) {
- return context.getRuntime().newBoolean(element.isInline());
- }
-
- @JRubyMethod(name="empty?")
- public IRubyObject empty_eh(ThreadContext context) {
- return context.getRuntime().newBoolean(element.isEmpty());
- }
-
- @JRubyMethod()
- public IRubyObject sub_elements(ThreadContext context) {
- Ruby ruby = context.getRuntime();
- List subs = findSubElements(element);
- IRubyObject[] ary = new IRubyObject[subs.size()];
- for (int i = 0; i < subs.size(); ++i) {
- ary[i] = ruby.newString(subs.get(i));
- }
-
- return ruby.newArray(ary);
- }
-
-}
diff --git a/ext/java/nokogiri/HtmlEntityLookup.java b/ext/java/nokogiri/HtmlEntityLookup.java
deleted file mode 100644
index 20ab5fd33d..0000000000
--- a/ext/java/nokogiri/HtmlEntityLookup.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * (The MIT License)
- *
- * Copyright (c) 2008 - 2012:
- *
- * * {Aaron Patterson}[http://tenderlovemaking.com]
- * * {Mike Dalessio}[http://mike.daless.io]
- * * {Charles Nutter}[http://blog.headius.com]
- * * {Sergio Arbeo}[http://www.serabe.com]
- * * {Patrick Mahoney}[http://polycrystal.org]
- * * {Yoko Harada}[http://yokolet.blogspot.com]
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * 'Software'), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-package nokogiri;
-
-import static org.jruby.runtime.Helpers.invoke;
-
-import org.cyberneko.html.HTMLEntities;
-import org.jruby.Ruby;
-import org.jruby.RubyClass;
-import org.jruby.RubyObject;
-import org.jruby.anno.JRubyClass;
-import org.jruby.anno.JRubyMethod;
-import org.jruby.runtime.ThreadContext;
-import org.jruby.runtime.builtin.IRubyObject;
-
-/**
- * Class for Nokogiri::HTML::EntityLookup.
- *
- * @author Patrick Mahoney
- */
-@JRubyClass(name="Nokogiri::HTML::EntityLookup")
-public class HtmlEntityLookup extends RubyObject {
-
- public HtmlEntityLookup(Ruby runtime, RubyClass rubyClass) {
- super(runtime, rubyClass);
- }
-
- /**
- * Looks up an HTML entity key.
- *
- * The description is a bit lacking.
- */
- @JRubyMethod()
- public IRubyObject get(ThreadContext context, IRubyObject key) {
- Ruby ruby = context.getRuntime();
- String name = key.toString();
- int val = HTMLEntities.get(name);
- if (val == -1) return ruby.getNil();
-
- IRubyObject edClass =
- ruby.getClassFromPath("Nokogiri::HTML::EntityDescription");
- IRubyObject edObj = invoke(context, edClass, "new",
- ruby.newFixnum(val), ruby.newString(name),
- ruby.newString(name + " entity"));
-
- return edObj;
- }
-
-}
diff --git a/ext/java/nokogiri/HtmlSaxParserContext.java b/ext/java/nokogiri/HtmlSaxParserContext.java
deleted file mode 100644
index 2fa4ee71c5..0000000000
--- a/ext/java/nokogiri/HtmlSaxParserContext.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/**
- * (The MIT License)
- *
- * Copyright (c) 2008 - 2011:
- *
- * * {Aaron Patterson}[http://tenderlovemaking.com]
- * * {Mike Dalessio}[http://mike.daless.io]
- * * {Charles Nutter}[http://blog.headius.com]
- * * {Sergio Arbeo}[http://www.serabe.com]
- * * {Patrick Mahoney}[http://polycrystal.org]
- * * {Yoko Harada}[http://yokolet.blogspot.com]
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * 'Software'), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-package nokogiri;
-
-import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.nio.charset.IllegalCharsetNameException;
-import java.nio.charset.UnsupportedCharsetException;
-import java.util.EnumSet;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import nokogiri.internals.NokogiriHandler;
-
-import org.apache.xerces.parsers.AbstractSAXParser;
-import org.cyberneko.html.parsers.SAXParser;
-import org.jruby.*;
-import org.jruby.anno.JRubyClass;
-import org.jruby.anno.JRubyMethod;
-import org.jruby.runtime.ThreadContext;
-import org.jruby.runtime.builtin.IRubyObject;
-import org.xml.sax.SAXException;
-
-/**
- * Class for Nokogiri::HTML::SAX::ParserContext.
- *
- * @author serabe
- * @author Patrick Mahoney
- * @author Yoko Harada
- */
-
-@JRubyClass(name="Nokogiri::HTML::SAX::ParserContext", parent="Nokogiri::XML::SAX::ParserContext")
-public class HtmlSaxParserContext extends XmlSaxParserContext {
-
- public HtmlSaxParserContext(Ruby ruby, RubyClass rubyClass) {
- super(ruby, rubyClass);
- }
-
- @Override
- protected AbstractSAXParser createParser() throws SAXException {
- SAXParser parser = new SAXParser();
-
- try{
- parser.setProperty(
- "http://cyberneko.org/html/properties/names/elems", "lower");
- parser.setProperty(
- "http://cyberneko.org/html/properties/names/attrs", "lower");
- return parser;
- } catch(SAXException ex) {
- throw new SAXException(
- "Problem while creating HTML SAX Parser: " + ex.toString());
- }
- }
-
- @JRubyMethod(name="memory", meta=true)
- public static IRubyObject parse_memory(ThreadContext context,
- IRubyObject klazz,
- IRubyObject data,
- IRubyObject encoding) {
- HtmlSaxParserContext ctx = (HtmlSaxParserContext) NokogiriService.HTML_SAXPARSER_CONTEXT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass)klazz);
- ctx.initialize(context.getRuntime());
- String javaEncoding = findEncoding(context, encoding);
- if (javaEncoding != null) {
- String input = applyEncoding(rubyStringToString(data), javaEncoding);
- ByteArrayInputStream istream = new ByteArrayInputStream(input.getBytes());
- ctx.setInputSource(istream);
- ctx.getInputSource().setEncoding(javaEncoding);
- }
- return ctx;
- }
-
- public enum EncodingType {
- NONE(0, "NONE"),
- UTF_8(1, "UTF-8"),
- UTF16LE(2, "UTF16LE"),
- UTF16BE(3, "UTF16BE"),
- UCS4LE(4, "UCS4LE"),
- UCS4BE(5, "UCS4BE"),
- EBCDIC(6, "EBCDIC"),
- UCS4_2143(7, "ICS4-2143"),
- UCS4_3412(8, "UCS4-3412"),
- UCS2(9, "UCS2"),
- ISO_8859_1(10, "ISO-8859-1"),
- ISO_8859_2(11, "ISO-8859-2"),
- ISO_8859_3(12, "ISO-8859-3"),
- ISO_8859_4(13, "ISO-8859-4"),
- ISO_8859_5(14, "ISO-8859-5"),
- ISO_8859_6(15, "ISO-8859-6"),
- ISO_8859_7(16, "ISO-8859-7"),
- ISO_8859_8(17, "ISO-8859-8"),
- ISO_8859_9(18, "ISO-8859-9"),
- ISO_2022_JP(19, "ISO-2022-JP"),
- SHIFT_JIS(20, "SHIFT-JIS"),
- EUC_JP(21, "EUC-JP"),
- ASCII(22, "ASCII");
-
- private final int value;
- private final String name;
-
- EncodingType(int value, String name) {
- this.value = value;
- this.name = name;
- }
-
- public int getValue() {
- return value;
- }
-
- public String toString() {
- return name;
- }
- }
-
- private static String findName(final int value) {
- for (EncodingType type : EncodingType.values()) {
- if (type.getValue() == value) return type.toString();
- }
- return null;
- }
-
- private static String findEncoding(ThreadContext context, IRubyObject encoding) {
- String rubyEncoding = null;
- if (encoding instanceof RubyString) {
- rubyEncoding = rubyStringToString(encoding);
- }
- else if (encoding instanceof RubyFixnum) {
- int value = RubyFixnum.fix2int((RubyFixnum) encoding);
- rubyEncoding = findName(value);
- }
- if (rubyEncoding == null) return null;
- try {
- return Charset.forName(rubyEncoding).displayName();
- }
- catch (UnsupportedCharsetException e) {
- throw context.getRuntime().newEncodingCompatibilityError(rubyEncoding + "is not supported");
- }
- catch (IllegalCharsetNameException e) {
- throw context.getRuntime().newInvalidEncoding(e.getMessage());
- }
- }
-
- private static final Pattern CHARSET_PATTERN = Pattern.compile("charset(()|\\s)=(()|\\s)([a-z]|-|_|\\d)+");
-
- private static String applyEncoding(String input, String enc) {
- String str = input.toLowerCase();
- int start_pos = 0;
- int end_pos = 0;
- if (input.contains("meta") && input.contains("charset")) {
- Matcher m = CHARSET_PATTERN.matcher(str);
- while (m.find()) {
- start_pos = m.start();
- end_pos = m.end();
- }
- }
- if (start_pos != end_pos) {
- String substr = input.substring(start_pos, end_pos);
- input = input.replace(substr, "charset=" + enc);
- }
- return input;
- }
-
- @JRubyMethod(name="file", meta=true)
- public static IRubyObject parse_file(ThreadContext context,
- IRubyObject klazz,
- IRubyObject data,
- IRubyObject encoding) {
- HtmlSaxParserContext ctx = (HtmlSaxParserContext) NokogiriService.HTML_SAXPARSER_CONTEXT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass)klazz);
- ctx.initialize(context.getRuntime());
- ctx.setInputSourceFile(context, data);
- String javaEncoding = findEncoding(context, encoding);
- if (javaEncoding != null) {
- ctx.getInputSource().setEncoding(javaEncoding);
- }
- return ctx;
- }
-
- @JRubyMethod(name="io", meta=true)
- public static IRubyObject parse_io(ThreadContext context,
- IRubyObject klazz,
- IRubyObject data,
- IRubyObject encoding) {
- HtmlSaxParserContext ctx = (HtmlSaxParserContext) NokogiriService.HTML_SAXPARSER_CONTEXT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass)klazz);
- ctx.initialize(context.getRuntime());
- ctx.setInputSource(context, data, context.getRuntime().getNil());
- String javaEncoding = findEncoding(context, encoding);
- if (javaEncoding != null) {
- ctx.getInputSource().setEncoding(javaEncoding);
- }
- return ctx;
- }
-
- /**
- * Create a new parser context that will read from a raw input stream.
- * Meant to be run in a separate thread by HtmlSaxPushParser.
- */
- static HtmlSaxParserContext parse_stream(final Ruby runtime, RubyClass klazz, InputStream stream) {
- HtmlSaxParserContext ctx = (HtmlSaxParserContext) NokogiriService.HTML_SAXPARSER_CONTEXT_ALLOCATOR.allocate(runtime, klazz);
- ctx.initialize(runtime);
- ctx.setInputSource(stream);
- return ctx;
- }
-
- @Override
- protected void preParse(final Ruby runtime, IRubyObject handlerRuby, NokogiriHandler handler) {
- // final String path = "Nokogiri::XML::FragmentHandler";
- // final String docFrag =
- // "http://cyberneko.org/html/features/balance-tags/document-fragment";
- // RubyObjectAdapter adapter = JavaEmbedUtils.newObjectAdapter();
- // IRubyObject doc = adapter.getInstanceVariable(handlerRuby, "@document");
- // RubyModule mod = runtime.getClassFromPath(path);
- // try {
- // if (doc != null && !doc.isNil() && adapter.isKindOf(doc, mod))
- // parser.setFeature(docFrag, true);
- // } catch (Exception e) {
- // // ignore
- // }
- }
-
-}
diff --git a/ext/java/nokogiri/HtmlSaxPushParser.java b/ext/java/nokogiri/HtmlSaxPushParser.java
deleted file mode 100644
index ae30a86f6d..0000000000
--- a/ext/java/nokogiri/HtmlSaxPushParser.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/**
- * (The MIT License)
- *
- * Copyright (c) 2008 - 2012:
- *
- * * {Aaron Patterson}[http://tenderlovemaking.com]
- * * {Mike Dalessio}[http://mike.daless.io]
- * * {Charles Nutter}[http://blog.headius.com]
- * * {Sergio Arbeo}[http://www.serabe.com]
- * * {Patrick Mahoney}[http://polycrystal.org]
- * * {Yoko Harada}[http://yokolet.blogspot.com]
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * 'Software'), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-package nokogiri;
-
-import static nokogiri.XmlSaxPushParser.terminateExecution;
-import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
-import static org.jruby.runtime.Helpers.invoke;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.ThreadFactory;
-
-import nokogiri.internals.*;
-
-import org.jruby.Ruby;
-import org.jruby.RubyClass;
-import org.jruby.RubyObject;
-import org.jruby.anno.JRubyClass;
-import org.jruby.anno.JRubyMethod;
-import org.jruby.exceptions.RaiseException;
-import org.jruby.runtime.ThreadContext;
-import org.jruby.runtime.builtin.IRubyObject;
-
-/**
- * Class for Nokogiri::HTML::SAX::PushParser
- *
- * @author
- * @author Piotr Szmielew - based on Nokogiri::XML::SAX::PushParser
- */
-@JRubyClass(name="Nokogiri::HTML::SAX::PushParser")
-public class HtmlSaxPushParser extends RubyObject {
- ParserContext.Options options;
- IRubyObject saxParser;
-
- NokogiriBlockingQueueInputStream stream;
-
- private ParserTask parserTask = null;
- private FutureTask futureTask = null;
- private ExecutorService executor = null;
-
- public HtmlSaxPushParser(Ruby ruby, RubyClass rubyClass) {
- super(ruby, rubyClass);
- }
-
- @Override
- public void finalize() {
- try {
- terminateImpl();
- }
- catch (Exception e) { /* ignored */ }
- }
-
- @JRubyMethod
- public IRubyObject initialize_native(final ThreadContext context,
- IRubyObject saxParser,
- IRubyObject fileName,
- IRubyObject encoding) {
- // NOTE: Silently skips provided encoding
- options = new ParserContext.Options(0);
- this.saxParser = saxParser;
- return this;
- }
-
- private transient IRubyObject parse_options;
-
- private IRubyObject parse_options(final ThreadContext context) {
- if (parse_options == null) {
- parse_options = invoke(context, context.runtime.getClassFromPath("Nokogiri::XML::ParseOptions"), "new");
- }
- return parse_options;
- }
-
- @JRubyMethod(name="options")
- public IRubyObject getOptions(ThreadContext context) {
- return invoke(context, parse_options(context), "options");
- }
-
- @JRubyMethod(name="options=")
- public IRubyObject setOptions(ThreadContext context, IRubyObject opts) {
- invoke(context, parse_options(context), "options=", opts);
- options = new ParserContext.Options(opts.convertToInteger().getLongValue());
- return getOptions(context);
- }
-
- @JRubyMethod
- public IRubyObject native_write(ThreadContext context, IRubyObject chunk, IRubyObject isLast) {
- try {
- initialize_task(context);
- } catch (IOException e) {
- throw context.getRuntime().newRuntimeError(e.getMessage());
- }
- final ByteArrayInputStream data = NokogiriHelpers.stringBytesToStream(chunk);
- if (data == null) {
- terminateTask(context.runtime);
- throw new RaiseException(XmlSyntaxError.createHTMLSyntaxError(context.runtime)); // Nokogiri::HTML::SyntaxError
- }
-
- int errorCount0 = parserTask.getErrorCount();
-
- if (isLast.isTrue()) {
- IRubyObject document = invoke(context, this, "document");
- invoke(context, document, "end_document");
- terminateTask(context.runtime);
- } else {
- try {
- Future task = stream.addChunk(data);
- task.get();
- }
- catch (ClosedStreamException ex) {
- // this means the stream is closed, ignore this exception
- }
- catch (Exception e) {
- throw context.runtime.newRuntimeError(e.getMessage());
- }
-
- }
-
- if (!options.recover && parserTask.getErrorCount() > errorCount0) {
- terminateTask(context.runtime);
- throw parserTask.getLastError();
- }
-
- return this;
- }
-
- @SuppressWarnings("unchecked")
- private void initialize_task(ThreadContext context) throws IOException {
- if (futureTask == null || stream == null) {
- stream = new NokogiriBlockingQueueInputStream();
-
- assert saxParser != null : "saxParser null";
- parserTask = new ParserTask(context, saxParser, stream);
- futureTask = new FutureTask((Callable) parserTask);
- executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
- @Override
- public Thread newThread(Runnable r) {
- Thread t = new Thread(r);
- t.setName("HtmlSaxPushParser");
- t.setDaemon(true);
- return t;
- }
- });
- executor.submit(futureTask);
- }
- }
-
- private void terminateTask(final Ruby runtime) {
- if (executor == null) return;
-
- try {
- terminateImpl();
- }
- catch (InterruptedException e) {
- throw runtime.newRuntimeError(e.toString());
- }
- catch (Exception e) {
- throw runtime.newRuntimeError(e.toString());
- }
- }
-
- private synchronized void terminateImpl() throws InterruptedException, ExecutionException {
- terminateExecution(executor, stream, futureTask);
-
- executor = null; stream = null; futureTask = null;
- }
-
- private static HtmlSaxParserContext parse(final Ruby runtime, final InputStream stream) {
- RubyClass klazz = getNokogiriClass(runtime, "Nokogiri::HTML::SAX::ParserContext");
- return HtmlSaxParserContext.parse_stream(runtime, klazz, stream);
- }
-
- static class ParserTask extends XmlSaxPushParser.ParserTask /* */ {
-
- private ParserTask(ThreadContext context, IRubyObject handler, InputStream stream) {
- super(context, handler, parse(context.runtime, stream), stream);
- }
-
- @Override
- public HtmlSaxParserContext call() throws Exception {
- return (HtmlSaxParserContext) super.call();
- }
-
- }
-
-}
diff --git a/ext/java/nokogiri/NokogiriService.java b/ext/java/nokogiri/NokogiriService.java
index 6b40e61260..a5d5b462ba 100644
--- a/ext/java/nokogiri/NokogiriService.java
+++ b/ext/java/nokogiri/NokogiriService.java
@@ -1,35 +1,3 @@
-/**
- * (The MIT License)
- *
- * Copyright (c) 2008 - 2011:
- *
- * * {Aaron Patterson}[http://tenderlovemaking.com]
- * * {Mike Dalessio}[http://mike.daless.io]
- * * {Charles Nutter}[http://blog.headius.com]
- * * {Sergio Arbeo}[http://www.serabe.com]
- * * {Patrick Mahoney}[http://polycrystal.org]
- * * {Yoko Harada}[http://yokolet.blogspot.com]
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * 'Software'), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
package nokogiri;
import java.util.Collections;
@@ -48,550 +16,598 @@
/**
* Class to provide Nokogiri. This class is used to make "require 'nokogiri'" work
* in JRuby. Also, this class holds a Ruby type cache and allocators of Ruby types.
- *
+ *
* @author headius
* @author Yoko Harada
*/
-public class NokogiriService implements BasicLibraryService {
- public boolean basicLoad(Ruby ruby) {
- init(ruby);
- return true;
+public class NokogiriService implements BasicLibraryService
+{
+ public boolean
+ basicLoad(Ruby ruby)
+ {
+ init(ruby);
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Map
+ getNokogiriClassCache(Ruby ruby)
+ {
+ return (Map) ruby.getModule("Nokogiri").getInternalVariable("cache");
+ }
+
+ private static Map
+ populateNokogiriClassCahce(Ruby ruby)
+ {
+ Map nokogiriClassCache = new HashMap();
+ nokogiriClassCache.put("Nokogiri::HTML4::Document", (RubyClass)ruby.getClassFromPath("Nokogiri::HTML4::Document"));
+ nokogiriClassCache.put("Nokogiri::HTML4::ElementDescription",
+ (RubyClass)ruby.getClassFromPath("Nokogiri::HTML4::ElementDescription"));
+ nokogiriClassCache.put("Nokogiri::XML::Attr", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Attr"));
+ nokogiriClassCache.put("Nokogiri::XML::Document", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Document"));
+ nokogiriClassCache.put("Nokogiri::XML::DocumentFragment",
+ (RubyClass)ruby.getClassFromPath("Nokogiri::XML::DocumentFragment"));
+ nokogiriClassCache.put("Nokogiri::XML::DTD", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::DTD"));
+ nokogiriClassCache.put("Nokogiri::XML::Text", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Text"));
+ nokogiriClassCache.put("Nokogiri::XML::Comment", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Comment"));
+ nokogiriClassCache.put("Nokogiri::XML::Element", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Element"));
+ nokogiriClassCache.put("Nokogiri::XML::ElementContent",
+ (RubyClass)ruby.getClassFromPath("Nokogiri::XML::ElementContent"));
+ nokogiriClassCache.put("Nokogiri::XML::ElementDecl", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::ElementDecl"));
+ nokogiriClassCache.put("Nokogiri::XML::EntityDecl", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::EntityDecl"));
+ nokogiriClassCache.put("Nokogiri::XML::EntityReference",
+ (RubyClass)ruby.getClassFromPath("Nokogiri::XML::EntityReference"));
+ nokogiriClassCache.put("Nokogiri::XML::ProcessingInstruction",
+ (RubyClass)ruby.getClassFromPath("Nokogiri::XML::ProcessingInstruction"));
+ nokogiriClassCache.put("Nokogiri::XML::CDATA", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::CDATA"));
+ nokogiriClassCache.put("Nokogiri::XML::Node", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Node"));
+ nokogiriClassCache.put("Nokogiri::XML::NodeSet", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::NodeSet"));
+ nokogiriClassCache.put("Nokogiri::XML::Namespace", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Namespace"));
+ nokogiriClassCache.put("Nokogiri::XML::SyntaxError", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::SyntaxError"));
+ nokogiriClassCache.put("Nokogiri::XML::Reader", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Reader"));
+ nokogiriClassCache.put("Nokogiri::XML::RelaxNG", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::RelaxNG"));
+ nokogiriClassCache.put("Nokogiri::XML::Schema", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Schema"));
+ nokogiriClassCache.put("Nokogiri::XML::XPathContext", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::XPathContext"));
+ nokogiriClassCache.put("Nokogiri::XML::AttributeDecl",
+ (RubyClass)ruby.getClassFromPath("Nokogiri::XML::AttributeDecl"));
+ nokogiriClassCache.put("Nokogiri::XML::SAX::ParserContext",
+ (RubyClass)ruby.getClassFromPath("Nokogiri::XML::SAX::ParserContext"));
+ return Collections.unmodifiableMap(nokogiriClassCache);
+ }
+
+ private void
+ init(Ruby ruby)
+ {
+ RubyModule nokogiri = ruby.defineModule("Nokogiri");
+ RubyModule xmlModule = nokogiri.defineModuleUnder("XML");
+ RubyModule xmlSaxModule = xmlModule.defineModuleUnder("SAX");
+ RubyModule htmlModule = nokogiri.defineModuleUnder("HTML4");
+ RubyModule htmlSaxModule = htmlModule.defineModuleUnder("SAX");
+ RubyModule xsltModule = nokogiri.defineModuleUnder("XSLT");
+
+ createSyntaxErrors(ruby, nokogiri, xmlModule);
+ RubyClass xmlNode = createXmlModule(ruby, xmlModule);
+ createHtmlModule(ruby, htmlModule);
+ createDocuments(ruby, xmlModule, htmlModule, xmlNode);
+ createSaxModule(ruby, xmlSaxModule, htmlSaxModule);
+ createXsltModule(ruby, xsltModule);
+ nokogiri.setInternalVariable("cache", populateNokogiriClassCahce(ruby));
+ }
+
+ private void
+ createSyntaxErrors(Ruby ruby, RubyModule nokogiri, RubyModule xmlModule)
+ {
+ RubyClass syntaxError = nokogiri.defineClassUnder("SyntaxError", ruby.getStandardError(),
+ ruby.getStandardError().getAllocator());
+ RubyClass xmlSyntaxError = xmlModule.defineClassUnder("SyntaxError", syntaxError, XML_SYNTAXERROR_ALLOCATOR);
+ xmlSyntaxError.defineAnnotatedMethods(XmlSyntaxError.class);
+ }
+
+ private RubyClass
+ createXmlModule(Ruby ruby, RubyModule xmlModule)
+ {
+ RubyClass node = xmlModule.defineClassUnder("Node", ruby.getObject(), XML_NODE_ALLOCATOR);
+ node.defineAnnotatedMethods(XmlNode.class);
+
+ RubyClass attr = xmlModule.defineClassUnder("Attr", node, XML_ATTR_ALLOCATOR);
+ attr.defineAnnotatedMethods(XmlAttr.class);
+
+ RubyClass attrDecl = xmlModule.defineClassUnder("AttributeDecl", node, XML_ATTRIBUTE_DECL_ALLOCATOR);
+ attrDecl.defineAnnotatedMethods(XmlAttributeDecl.class);
+
+ RubyClass characterData = xmlModule.defineClassUnder("CharacterData", node, null);
+
+ RubyClass comment = xmlModule.defineClassUnder("Comment", characterData, XML_COMMENT_ALLOCATOR);
+ comment.defineAnnotatedMethods(XmlComment.class);
+
+ RubyClass text = xmlModule.defineClassUnder("Text", characterData, XML_TEXT_ALLOCATOR);
+ text.defineAnnotatedMethods(XmlText.class);
+
+ RubyModule cdata = xmlModule.defineClassUnder("CDATA", text, XML_CDATA_ALLOCATOR);
+ cdata.defineAnnotatedMethods(XmlCdata.class);
+
+ RubyClass dtd = xmlModule.defineClassUnder("DTD", node, XML_DTD_ALLOCATOR);
+ dtd.defineAnnotatedMethods(XmlDtd.class);
+
+ RubyClass documentFragment = xmlModule.defineClassUnder("DocumentFragment", node, XML_DOCUMENT_FRAGMENT_ALLOCATOR);
+ documentFragment.defineAnnotatedMethods(XmlDocumentFragment.class);
+
+ RubyClass element = xmlModule.defineClassUnder("Element", node, XML_ELEMENT_ALLOCATOR);
+ element.defineAnnotatedMethods(XmlElement.class);
+
+ RubyClass elementContent = xmlModule.defineClassUnder("ElementContent", ruby.getObject(),
+ XML_ELEMENT_CONTENT_ALLOCATOR);
+ elementContent.defineAnnotatedMethods(XmlElementContent.class);
+
+ RubyClass elementDecl = xmlModule.defineClassUnder("ElementDecl", node, XML_ELEMENT_DECL_ALLOCATOR);
+ elementDecl.defineAnnotatedMethods(XmlElementDecl.class);
+
+ RubyClass entityDecl = xmlModule.defineClassUnder("EntityDecl", node, XML_ENTITY_DECL_ALLOCATOR);
+ entityDecl.defineAnnotatedMethods(XmlEntityDecl.class);
+
+ entityDecl.defineConstant("INTERNAL_GENERAL", RubyFixnum.newFixnum(ruby, XmlEntityDecl.INTERNAL_GENERAL));
+ entityDecl.defineConstant("EXTERNAL_GENERAL_PARSED", RubyFixnum.newFixnum(ruby, XmlEntityDecl.EXTERNAL_GENERAL_PARSED));
+ entityDecl.defineConstant("EXTERNAL_GENERAL_UNPARSED", RubyFixnum.newFixnum(ruby,
+ XmlEntityDecl.EXTERNAL_GENERAL_UNPARSED));
+ entityDecl.defineConstant("INTERNAL_PARAMETER", RubyFixnum.newFixnum(ruby, XmlEntityDecl.INTERNAL_PARAMETER));
+ entityDecl.defineConstant("EXTERNAL_PARAMETER", RubyFixnum.newFixnum(ruby, XmlEntityDecl.EXTERNAL_PARAMETER));
+ entityDecl.defineConstant("INTERNAL_PREDEFINED", RubyFixnum.newFixnum(ruby, XmlEntityDecl.INTERNAL_PREDEFINED));
+
+ RubyClass entref = xmlModule.defineClassUnder("EntityReference", node, XML_ENTITY_REFERENCE_ALLOCATOR);
+ entref.defineAnnotatedMethods(XmlEntityReference.class);
+
+ RubyClass namespace = xmlModule.defineClassUnder("Namespace", ruby.getObject(), XML_NAMESPACE_ALLOCATOR);
+ namespace.defineAnnotatedMethods(XmlNamespace.class);
+
+ RubyClass nodeSet = xmlModule.defineClassUnder("NodeSet", ruby.getObject(), XML_NODESET_ALLOCATOR);
+ nodeSet.defineAnnotatedMethods(XmlNodeSet.class);
+
+ RubyClass pi = xmlModule.defineClassUnder("ProcessingInstruction", node, XML_PROCESSING_INSTRUCTION_ALLOCATOR);
+ pi.defineAnnotatedMethods(XmlProcessingInstruction.class);
+
+ RubyClass reader = xmlModule.defineClassUnder("Reader", ruby.getObject(), XML_READER_ALLOCATOR);
+ reader.defineAnnotatedMethods(XmlReader.class);
+
+ RubyClass schema = xmlModule.defineClassUnder("Schema", ruby.getObject(), XML_SCHEMA_ALLOCATOR);
+ schema.defineAnnotatedMethods(XmlSchema.class);
+
+ RubyClass relaxng = xmlModule.defineClassUnder("RelaxNG", schema, XML_RELAXNG_ALLOCATOR);
+ relaxng.defineAnnotatedMethods(XmlRelaxng.class);
+
+ RubyClass xpathContext = xmlModule.defineClassUnder("XPathContext", ruby.getObject(), XML_XPATHCONTEXT_ALLOCATOR);
+ xpathContext.defineAnnotatedMethods(XmlXpathContext.class);
+
+ return node;
+ }
+
+ private void
+ createHtmlModule(Ruby ruby, RubyModule htmlModule)
+ {
+ RubyClass htmlElemDesc = htmlModule.defineClassUnder("ElementDescription", ruby.getObject(),
+ HTML_ELEMENT_DESCRIPTION_ALLOCATOR);
+ htmlElemDesc.defineAnnotatedMethods(Html4ElementDescription.class);
+
+ RubyClass htmlEntityLookup = htmlModule.defineClassUnder("EntityLookup", ruby.getObject(),
+ HTML_ENTITY_LOOKUP_ALLOCATOR);
+ htmlEntityLookup.defineAnnotatedMethods(Html4EntityLookup.class);
+ }
+
+ private void
+ createDocuments(Ruby ruby, RubyModule xmlModule, RubyModule htmlModule, RubyClass node)
+ {
+ RubyClass xmlDocument = xmlModule.defineClassUnder("Document", node, XML_DOCUMENT_ALLOCATOR);
+ xmlDocument.defineAnnotatedMethods(XmlDocument.class);
+
+ //RubyModule htmlDoc = html.defineOrGetClassUnder("Document", document);
+ RubyModule htmlDocument = htmlModule.defineClassUnder("Document", xmlDocument, HTML_DOCUMENT_ALLOCATOR);
+ htmlDocument.defineAnnotatedMethods(Html4Document.class);
+ }
+
+ private void
+ createSaxModule(Ruby ruby, RubyModule xmlSaxModule, RubyModule htmlSaxModule)
+ {
+ RubyClass xmlSaxParserContext = xmlSaxModule.defineClassUnder("ParserContext", ruby.getObject(),
+ XML_SAXPARSER_CONTEXT_ALLOCATOR);
+ xmlSaxParserContext.defineAnnotatedMethods(XmlSaxParserContext.class);
+
+ RubyClass xmlSaxPushParser = xmlSaxModule.defineClassUnder("PushParser", ruby.getObject(), XML_SAXPUSHPARSER_ALLOCATOR);
+ xmlSaxPushParser.defineAnnotatedMethods(XmlSaxPushParser.class);
+
+ RubyClass htmlSaxPushParser = htmlSaxModule.defineClassUnder("PushParser", ruby.getObject(),
+ HTML_SAXPUSHPARSER_ALLOCATOR);
+ htmlSaxPushParser.defineAnnotatedMethods(Html4SaxPushParser.class);
+
+ RubyClass htmlSaxParserContext = htmlSaxModule.defineClassUnder("ParserContext", xmlSaxParserContext,
+ HTML_SAXPARSER_CONTEXT_ALLOCATOR);
+ htmlSaxParserContext.defineAnnotatedMethods(Html4SaxParserContext.class);
+ }
+
+ private void
+ createXsltModule(Ruby ruby, RubyModule xsltModule)
+ {
+ RubyClass stylesheet = xsltModule.defineClassUnder("Stylesheet", ruby.getObject(), XSLT_STYLESHEET_ALLOCATOR);
+ stylesheet.defineAnnotatedMethods(XsltStylesheet.class);
+ xsltModule.defineAnnotatedMethod(XsltStylesheet.class, "register");
+ }
+
+ public static final ObjectAllocator HTML_DOCUMENT_ALLOCATOR = new ObjectAllocator()
+ {
+ private Html4Document htmlDocument = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (htmlDocument == null) { htmlDocument = new Html4Document(runtime, klazz); }
+ try {
+ Html4Document clone = (Html4Document) htmlDocument.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new Html4Document(runtime, klazz);
+ }
}
+ };
+
+ private static final ObjectAllocator HTML_SAXPARSER_CONTEXT_ALLOCATOR = new ObjectAllocator()
+ {
+ private Html4SaxParserContext htmlSaxParserContext = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (htmlSaxParserContext == null) { htmlSaxParserContext = new Html4SaxParserContext(runtime, klazz); }
+ try {
+ Html4SaxParserContext clone = (Html4SaxParserContext) htmlSaxParserContext.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new Html4SaxParserContext(runtime, klazz);
+ }
+ }
+ };
- public static Map getNokogiriClassCache(Ruby ruby) {
- return (Map) ruby.getModule("Nokogiri").getInternalVariable("cache");
+ private static ObjectAllocator HTML_ELEMENT_DESCRIPTION_ALLOCATOR =
+ new ObjectAllocator()
+ {
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ return new Html4ElementDescription(runtime, klazz);
}
+ };
- private static Map populateNokogiriClassCahce(Ruby ruby) {
- Map nokogiriClassCache = new HashMap();
- nokogiriClassCache.put("Nokogiri::EncodingHandler", (RubyClass)ruby.getClassFromPath("Nokogiri::EncodingHandler"));
- nokogiriClassCache.put("Nokogiri::HTML::Document", (RubyClass)ruby.getClassFromPath("Nokogiri::HTML::Document"));
- nokogiriClassCache.put("Nokogiri::HTML::ElementDescription", (RubyClass)ruby.getClassFromPath("Nokogiri::HTML::ElementDescription"));
- nokogiriClassCache.put("Nokogiri::XML::Attr", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Attr"));
- nokogiriClassCache.put("Nokogiri::XML::Document", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Document"));
- nokogiriClassCache.put("Nokogiri::XML::DocumentFragment", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::DocumentFragment"));
- nokogiriClassCache.put("Nokogiri::XML::DTD", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::DTD"));
- nokogiriClassCache.put("Nokogiri::XML::Text", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Text"));
- nokogiriClassCache.put("Nokogiri::XML::Comment", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Comment"));
- nokogiriClassCache.put("Nokogiri::XML::Element", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Element"));
- nokogiriClassCache.put("Nokogiri::XML::ElementContent", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::ElementContent"));
- nokogiriClassCache.put("Nokogiri::XML::ElementDecl", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::ElementDecl"));
- nokogiriClassCache.put("Nokogiri::XML::EntityDecl", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::EntityDecl"));
- nokogiriClassCache.put("Nokogiri::XML::EntityReference", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::EntityReference"));
- nokogiriClassCache.put("Nokogiri::XML::ProcessingInstruction", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::ProcessingInstruction"));
- nokogiriClassCache.put("Nokogiri::XML::CDATA", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::CDATA"));
- nokogiriClassCache.put("Nokogiri::XML::Node", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Node"));
- nokogiriClassCache.put("Nokogiri::XML::NodeSet", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::NodeSet"));
- nokogiriClassCache.put("Nokogiri::XML::Namespace", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Namespace"));
- nokogiriClassCache.put("Nokogiri::XML::SyntaxError", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::SyntaxError"));
- nokogiriClassCache.put("Nokogiri::XML::Reader", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Reader"));
- nokogiriClassCache.put("Nokogiri::XML::RelaxNG", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::RelaxNG"));
- nokogiriClassCache.put("Nokogiri::XML::Schema", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Schema"));
- nokogiriClassCache.put("Nokogiri::XML::XPathContext", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::XPathContext"));
- nokogiriClassCache.put("Nokogiri::XML::AttributeDecl", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::AttributeDecl"));
- nokogiriClassCache.put("Nokogiri::XML::SAX::ParserContext", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::SAX::ParserContext"));
- return Collections.unmodifiableMap(nokogiriClassCache);
+ private static ObjectAllocator HTML_ENTITY_LOOKUP_ALLOCATOR =
+ new ObjectAllocator()
+ {
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ return new Html4EntityLookup(runtime, klazz);
+ }
+ };
+
+ public static final ObjectAllocator XML_ATTR_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlAttr xmlAttr = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlAttr == null) { xmlAttr = new XmlAttr(runtime, klazz); }
+ try {
+ XmlAttr clone = (XmlAttr) xmlAttr.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlAttr(runtime, klazz);
+ }
+ }
+ };
+
+ public static final ObjectAllocator XML_CDATA_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlCdata xmlCdata = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlCdata == null) { xmlCdata = new XmlCdata(runtime, klazz); }
+ try {
+ XmlCdata clone = (XmlCdata) xmlCdata.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlCdata(runtime, klazz);
+ }
+ }
+ };
+
+ public static final ObjectAllocator XML_COMMENT_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlComment xmlComment = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlComment == null) { xmlComment = new XmlComment(runtime, klazz); }
+ try {
+ XmlComment clone = (XmlComment) xmlComment.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlComment(runtime, klazz);
+ }
+ }
+ };
+
+ public static final ObjectAllocator XML_DOCUMENT_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlDocument xmlDocument = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlDocument == null) { xmlDocument = new XmlDocument(runtime, klazz); }
+ try {
+ XmlDocument clone = (XmlDocument) xmlDocument.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlDocument(runtime, klazz);
+ }
+ }
+ };
+
+ public static final ObjectAllocator XML_DOCUMENT_FRAGMENT_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlDocumentFragment xmlDocumentFragment = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlDocumentFragment == null) { xmlDocumentFragment = new XmlDocumentFragment(runtime, klazz); }
+ try {
+ XmlDocumentFragment clone = (XmlDocumentFragment)xmlDocumentFragment.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlDocumentFragment(runtime, klazz);
+ }
+ }
+ };
+
+ public static final ObjectAllocator XML_DTD_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlDtd xmlDtd = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlDtd == null) { xmlDtd = new XmlDtd(runtime, klazz); }
+ try {
+ XmlDtd clone = (XmlDtd)xmlDtd.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlDtd(runtime, klazz);
+ }
}
+ };
+
+ public static final ObjectAllocator XML_ELEMENT_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlElement xmlElement = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlElement == null) { xmlElement = new XmlElement(runtime, klazz); }
+ try {
+ XmlElement clone = (XmlElement)xmlElement.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlElement(runtime, klazz);
+ }
+ }
+ };
+
+ public static ObjectAllocator XML_ELEMENT_DECL_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlElementDecl xmlElementDecl = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlElementDecl == null) { xmlElementDecl = new XmlElementDecl(runtime, klazz); }
+ try {
+ XmlElementDecl clone = (XmlElementDecl)xmlElementDecl.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlElementDecl(runtime, klazz);
+ }
+ }
+ };
+
+ public static ObjectAllocator XML_ENTITY_REFERENCE_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlEntityReference xmlEntityRef = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlEntityRef == null) { xmlEntityRef = new XmlEntityReference(runtime, klazz); }
+ try {
+ XmlEntityReference clone = (XmlEntityReference)xmlEntityRef.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlEntityReference(runtime, klazz);
+ }
+ }
+ };
+
+ public static final ObjectAllocator XML_NAMESPACE_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlNamespace xmlNamespace = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlNamespace == null) { xmlNamespace = new XmlNamespace(runtime, klazz); }
+ try {
+ XmlNamespace clone = (XmlNamespace) xmlNamespace.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlNamespace(runtime, klazz);
+ }
+ }
+ };
+
+ public static final ObjectAllocator XML_NODE_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlNode xmlNode = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlNode == null) { xmlNode = new XmlNode(runtime, klazz); }
+ try {
+ XmlNode clone = (XmlNode) xmlNode.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlNode(runtime, klazz);
+ }
+ }
+ };
+
+ public static final ObjectAllocator XML_NODESET_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlNodeSet xmlNodeSet = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlNodeSet == null) { xmlNodeSet = new XmlNodeSet(runtime, klazz); }
+ try {
+ XmlNodeSet clone = (XmlNodeSet) xmlNodeSet.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlNodeSet(runtime, klazz);
+ }
+ }
+ };
+
+ public static ObjectAllocator XML_PROCESSING_INSTRUCTION_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlProcessingInstruction xmlProcessingInstruction = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlProcessingInstruction == null) { xmlProcessingInstruction = new XmlProcessingInstruction(runtime, klazz); }
+ try {
+ XmlProcessingInstruction clone = (XmlProcessingInstruction)xmlProcessingInstruction.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlProcessingInstruction(runtime, klazz);
+ }
+ }
+ };
+
+ public static ObjectAllocator XML_READER_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlReader xmlReader = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlReader == null) { xmlReader = new XmlReader(runtime, klazz); }
+ try {
+ XmlReader clone = (XmlReader) xmlReader.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ xmlReader = new XmlReader(runtime, klazz);
+ return xmlReader;
+ }
+ }
+ };
- private void init(Ruby ruby) {
- RubyModule nokogiri = ruby.defineModule("Nokogiri");
- RubyModule xmlModule = nokogiri.defineModuleUnder("XML");
- RubyModule xmlSaxModule = xmlModule.defineModuleUnder("SAX");
- RubyModule htmlModule = nokogiri.defineModuleUnder("HTML");
- RubyModule htmlSaxModule = htmlModule.defineModuleUnder("SAX");
- RubyModule xsltModule = nokogiri.defineModuleUnder("XSLT");
-
- createJavaLibraryVersionConstants(ruby, nokogiri);
- createNokogiriModule(ruby, nokogiri);
- createSyntaxErrors(ruby, nokogiri, xmlModule);
- RubyClass xmlNode = createXmlModule(ruby, xmlModule);
- createHtmlModule(ruby, htmlModule);
- createDocuments(ruby, xmlModule, htmlModule, xmlNode);
- createSaxModule(ruby, xmlSaxModule, htmlSaxModule);
- createXsltModule(ruby, xsltModule);
- nokogiri.setInternalVariable("cache", populateNokogiriClassCahce(ruby));
+ private static ObjectAllocator XML_ATTRIBUTE_DECL_ALLOCATOR = new ObjectAllocator()
+ {
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ return new XmlAttributeDecl(runtime, klazz);
}
+ };
- private void createJavaLibraryVersionConstants(Ruby ruby, RubyModule nokogiri) {
- nokogiri.defineConstant("XERCES_VERSION", ruby.newString(org.apache.xerces.impl.Version.getVersion()));
- nokogiri.defineConstant("NEKO_VERSION", ruby.newString(org.cyberneko.html.Version.getVersion()));
+ private static ObjectAllocator XML_ENTITY_DECL_ALLOCATOR = new ObjectAllocator()
+ {
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ return new XmlEntityDecl(runtime, klazz);
}
+ };
- private void createNokogiriModule(Ruby ruby, RubyModule nokogiri) {
- RubyClass encHandler = nokogiri.defineClassUnder("EncodingHandler", ruby.getObject(), ENCODING_HANDLER_ALLOCATOR);
- encHandler.defineAnnotatedMethods(EncodingHandler.class);
+ private static ObjectAllocator XML_ELEMENT_CONTENT_ALLOCATOR = new ObjectAllocator()
+ {
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ throw runtime.newNotImplementedError("not implemented");
+ }
+ };
+
+ public static final ObjectAllocator XML_RELAXNG_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlRelaxng xmlRelaxng = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlRelaxng == null) { xmlRelaxng = new XmlRelaxng(runtime, klazz); }
+ try {
+ XmlRelaxng clone = (XmlRelaxng) xmlRelaxng.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlRelaxng(runtime, klazz);
+ }
}
-
- private void createSyntaxErrors(Ruby ruby, RubyModule nokogiri, RubyModule xmlModule) {
- RubyClass syntaxError = nokogiri.defineClassUnder("SyntaxError", ruby.getStandardError(), ruby.getStandardError().getAllocator());
- RubyClass xmlSyntaxError = xmlModule.defineClassUnder("SyntaxError", syntaxError, XML_SYNTAXERROR_ALLOCATOR);
- xmlSyntaxError.defineAnnotatedMethods(XmlSyntaxError.class);
+ };
+
+ public static final ObjectAllocator XML_SAXPARSER_CONTEXT_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlSaxParserContext xmlSaxParserContext = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlSaxParserContext == null) { xmlSaxParserContext = new XmlSaxParserContext(runtime, klazz); }
+ try {
+ XmlSaxParserContext clone = (XmlSaxParserContext) xmlSaxParserContext.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlSaxParserContext(runtime, klazz);
+ }
}
-
- private RubyClass createXmlModule(Ruby ruby, RubyModule xmlModule) {
- RubyClass node = xmlModule.defineClassUnder("Node", ruby.getObject(), XML_NODE_ALLOCATOR);
- node.defineAnnotatedMethods(XmlNode.class);
-
- RubyClass attr = xmlModule.defineClassUnder("Attr", node, XML_ATTR_ALLOCATOR);
- attr.defineAnnotatedMethods(XmlAttr.class);
-
- RubyClass attrDecl = xmlModule.defineClassUnder("AttributeDecl", node, XML_ATTRIBUTE_DECL_ALLOCATOR);
- attrDecl.defineAnnotatedMethods(XmlAttributeDecl.class);
-
- RubyClass characterData = xmlModule.defineClassUnder("CharacterData", node, null);
-
- RubyClass comment = xmlModule.defineClassUnder("Comment", characterData, XML_COMMENT_ALLOCATOR);
- comment.defineAnnotatedMethods(XmlComment.class);
-
- RubyClass text = xmlModule.defineClassUnder("Text", characterData, XML_TEXT_ALLOCATOR);
- text.defineAnnotatedMethods(XmlText.class);
-
- RubyModule cdata = xmlModule.defineClassUnder("CDATA", text, XML_CDATA_ALLOCATOR);
- cdata.defineAnnotatedMethods(XmlCdata.class);
-
- RubyClass dtd = xmlModule.defineClassUnder("DTD", node, XML_DTD_ALLOCATOR);
- dtd.defineAnnotatedMethods(XmlDtd.class);
-
- RubyClass documentFragment = xmlModule.defineClassUnder("DocumentFragment", node, XML_DOCUMENT_FRAGMENT_ALLOCATOR);
- documentFragment.defineAnnotatedMethods(XmlDocumentFragment.class);
-
- RubyClass element = xmlModule.defineClassUnder("Element", node, XML_ELEMENT_ALLOCATOR);
- element.defineAnnotatedMethods(XmlElement.class);
-
- RubyClass elementContent = xmlModule.defineClassUnder("ElementContent", ruby.getObject(), XML_ELEMENT_CONTENT_ALLOCATOR);
- elementContent.defineAnnotatedMethods(XmlElementContent.class);
-
- RubyClass elementDecl = xmlModule.defineClassUnder("ElementDecl", node, XML_ELEMENT_DECL_ALLOCATOR);
- elementDecl.defineAnnotatedMethods(XmlElementDecl.class);
-
- RubyClass entityDecl = xmlModule.defineClassUnder("EntityDecl", node, XML_ENTITY_DECL_ALLOCATOR);
- entityDecl.defineAnnotatedMethods(XmlEntityDecl.class);
-
- entityDecl.defineConstant("INTERNAL_GENERAL", RubyFixnum.newFixnum(ruby, XmlEntityDecl.INTERNAL_GENERAL));
- entityDecl.defineConstant("EXTERNAL_GENERAL_PARSED", RubyFixnum.newFixnum(ruby, XmlEntityDecl.EXTERNAL_GENERAL_PARSED));
- entityDecl.defineConstant("EXTERNAL_GENERAL_UNPARSED", RubyFixnum.newFixnum(ruby, XmlEntityDecl.EXTERNAL_GENERAL_UNPARSED));
- entityDecl.defineConstant("INTERNAL_PARAMETER", RubyFixnum.newFixnum(ruby, XmlEntityDecl.INTERNAL_PARAMETER));
- entityDecl.defineConstant("EXTERNAL_PARAMETER", RubyFixnum.newFixnum(ruby, XmlEntityDecl.EXTERNAL_PARAMETER));
- entityDecl.defineConstant("INTERNAL_PREDEFINED", RubyFixnum.newFixnum(ruby, XmlEntityDecl.INTERNAL_PREDEFINED));
-
- RubyClass entref = xmlModule.defineClassUnder("EntityReference", node, XML_ENTITY_REFERENCE_ALLOCATOR);
- entref.defineAnnotatedMethods(XmlEntityReference.class);
-
- RubyClass namespace = xmlModule.defineClassUnder("Namespace", ruby.getObject(), XML_NAMESPACE_ALLOCATOR);
- namespace.defineAnnotatedMethods(XmlNamespace.class);
-
- RubyClass nodeSet = xmlModule.defineClassUnder("NodeSet", ruby.getObject(), XML_NODESET_ALLOCATOR);
- nodeSet.defineAnnotatedMethods(XmlNodeSet.class);
-
- RubyClass pi = xmlModule.defineClassUnder("ProcessingInstruction", node, XML_PROCESSING_INSTRUCTION_ALLOCATOR);
- pi.defineAnnotatedMethods(XmlProcessingInstruction.class);
-
- RubyClass reader = xmlModule.defineClassUnder("Reader", ruby.getObject(), XML_READER_ALLOCATOR);
- reader.defineAnnotatedMethods(XmlReader.class);
-
- RubyClass schema = xmlModule.defineClassUnder("Schema", ruby.getObject(), XML_SCHEMA_ALLOCATOR);
- schema.defineAnnotatedMethods(XmlSchema.class);
-
- RubyClass relaxng = xmlModule.defineClassUnder("RelaxNG", schema, XML_RELAXNG_ALLOCATOR);
- relaxng.defineAnnotatedMethods(XmlRelaxng.class);
-
- RubyClass xpathContext = xmlModule.defineClassUnder("XPathContext", ruby.getObject(), XML_XPATHCONTEXT_ALLOCATOR);
- xpathContext.defineAnnotatedMethods(XmlXpathContext.class);
-
- return node;
+ };
+
+ private static final ObjectAllocator XML_SAXPUSHPARSER_ALLOCATOR = new ObjectAllocator()
+ {
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ return new XmlSaxPushParser(runtime, klazz);
}
+ };
- private void createHtmlModule(Ruby ruby, RubyModule htmlModule) {
- RubyClass htmlElemDesc = htmlModule.defineClassUnder("ElementDescription", ruby.getObject(), HTML_ELEMENT_DESCRIPTION_ALLOCATOR);
- htmlElemDesc.defineAnnotatedMethods(HtmlElementDescription.class);
-
- RubyClass htmlEntityLookup = htmlModule.defineClassUnder("EntityLookup", ruby.getObject(), HTML_ENTITY_LOOKUP_ALLOCATOR);
- htmlEntityLookup.defineAnnotatedMethods(HtmlEntityLookup.class);
+ private static final ObjectAllocator HTML_SAXPUSHPARSER_ALLOCATOR = new ObjectAllocator()
+ {
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ return new Html4SaxPushParser(runtime, klazz);
}
-
- private void createDocuments(Ruby ruby, RubyModule xmlModule, RubyModule htmlModule, RubyClass node) {
- RubyClass xmlDocument = xmlModule.defineClassUnder("Document", node, XML_DOCUMENT_ALLOCATOR);
- xmlDocument.defineAnnotatedMethods(XmlDocument.class);
-
- //RubyModule htmlDoc = html.defineOrGetClassUnder("Document", document);
- RubyModule htmlDocument = htmlModule.defineClassUnder("Document", xmlDocument, HTML_DOCUMENT_ALLOCATOR);
- htmlDocument.defineAnnotatedMethods(HtmlDocument.class);
+ };
+
+ public static final ObjectAllocator XML_SCHEMA_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlSchema xmlSchema = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlSchema == null) { xmlSchema = new XmlSchema(runtime, klazz); }
+ try {
+ XmlSchema clone = (XmlSchema) xmlSchema.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlSchema(runtime, klazz);
+ }
}
-
- private void createSaxModule(Ruby ruby, RubyModule xmlSaxModule, RubyModule htmlSaxModule) {
- RubyClass xmlSaxParserContext = xmlSaxModule.defineClassUnder("ParserContext", ruby.getObject(), XML_SAXPARSER_CONTEXT_ALLOCATOR);
- xmlSaxParserContext.defineAnnotatedMethods(XmlSaxParserContext.class);
-
- RubyClass xmlSaxPushParser = xmlSaxModule.defineClassUnder("PushParser", ruby.getObject(), XML_SAXPUSHPARSER_ALLOCATOR);
- xmlSaxPushParser.defineAnnotatedMethods(XmlSaxPushParser.class);
-
- RubyClass htmlSaxPushParser = htmlSaxModule.defineClassUnder("PushParser", ruby.getObject(), HTML_SAXPUSHPARSER_ALLOCATOR);
- htmlSaxPushParser.defineAnnotatedMethods(HtmlSaxPushParser.class);
-
- RubyClass htmlSaxParserContext = htmlSaxModule.defineClassUnder("ParserContext", xmlSaxParserContext, HTML_SAXPARSER_CONTEXT_ALLOCATOR);
- htmlSaxParserContext.defineAnnotatedMethods(HtmlSaxParserContext.class);
+ };
+
+ public static final ObjectAllocator XML_SYNTAXERROR_ALLOCATOR = new ObjectAllocator()
+ {
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ return new XmlSyntaxError(runtime, klazz);
}
-
- private void createXsltModule(Ruby ruby, RubyModule xsltModule) {
- RubyClass stylesheet = xsltModule.defineClassUnder("Stylesheet", ruby.getObject(), XSLT_STYLESHEET_ALLOCATOR);
- stylesheet.defineAnnotatedMethods(XsltStylesheet.class);
- xsltModule.defineAnnotatedMethod(XsltStylesheet.class, "register");
+ };
+
+ public static final ObjectAllocator XML_TEXT_ALLOCATOR = new ObjectAllocator()
+ {
+ private XmlText xmlText = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xmlText == null) { xmlText = new XmlText(runtime, klazz); }
+ try {
+ XmlText clone = (XmlText) xmlText.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlText(runtime, klazz);
+ }
}
+ };
- private static ObjectAllocator ENCODING_HANDLER_ALLOCATOR = new ObjectAllocator() {
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- return new EncodingHandler(runtime, klazz, "");
- }
- };
-
- public static final ObjectAllocator HTML_DOCUMENT_ALLOCATOR = new ObjectAllocator() {
- private HtmlDocument htmlDocument = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (htmlDocument == null) htmlDocument = new HtmlDocument(runtime, klazz);
- try {
- HtmlDocument clone = (HtmlDocument) htmlDocument.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new HtmlDocument(runtime, klazz);
- }
- }
- };
-
- public static final ObjectAllocator HTML_SAXPARSER_CONTEXT_ALLOCATOR = new ObjectAllocator() {
- private HtmlSaxParserContext htmlSaxParserContext = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (htmlSaxParserContext == null) htmlSaxParserContext = new HtmlSaxParserContext(runtime, klazz);
- try {
- HtmlSaxParserContext clone = (HtmlSaxParserContext) htmlSaxParserContext.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new HtmlSaxParserContext(runtime, klazz);
- }
- }
- };
-
- private static ObjectAllocator HTML_ELEMENT_DESCRIPTION_ALLOCATOR =
- new ObjectAllocator() {
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- return new HtmlElementDescription(runtime, klazz);
- }
- };
-
- private static ObjectAllocator HTML_ENTITY_LOOKUP_ALLOCATOR =
- new ObjectAllocator() {
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- return new HtmlEntityLookup(runtime, klazz);
- }
- };
-
- public static final ObjectAllocator XML_ATTR_ALLOCATOR = new ObjectAllocator() {
- private XmlAttr xmlAttr = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlAttr == null) xmlAttr = new XmlAttr(runtime, klazz);
- try {
- XmlAttr clone = (XmlAttr) xmlAttr.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlAttr(runtime, klazz);
- }
- }
- };
-
- public static final ObjectAllocator XML_CDATA_ALLOCATOR = new ObjectAllocator() {
- private XmlCdata xmlCdata = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlCdata == null) xmlCdata = new XmlCdata(runtime, klazz);
- try {
- XmlCdata clone = (XmlCdata) xmlCdata.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlCdata(runtime, klazz);
- }
- }
- };
-
- public static final ObjectAllocator XML_COMMENT_ALLOCATOR = new ObjectAllocator() {
- private XmlComment xmlComment = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlComment == null) xmlComment = new XmlComment(runtime, klazz);
- try {
- XmlComment clone = (XmlComment) xmlComment.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlComment(runtime, klazz);
- }
- }
- };
-
- public static final ObjectAllocator XML_DOCUMENT_ALLOCATOR = new ObjectAllocator() {
- private XmlDocument xmlDocument = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlDocument == null) xmlDocument = new XmlDocument(runtime, klazz);
- try {
- XmlDocument clone = (XmlDocument) xmlDocument.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlDocument(runtime, klazz);
- }
- }
- };
-
- public static final ObjectAllocator XML_DOCUMENT_FRAGMENT_ALLOCATOR = new ObjectAllocator() {
- private XmlDocumentFragment xmlDocumentFragment = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlDocumentFragment == null) xmlDocumentFragment = new XmlDocumentFragment(runtime, klazz);
- try {
- XmlDocumentFragment clone = (XmlDocumentFragment)xmlDocumentFragment.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlDocumentFragment(runtime, klazz);
- }
- }
- };
-
- public static final ObjectAllocator XML_DTD_ALLOCATOR = new ObjectAllocator() {
- private XmlDtd xmlDtd = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlDtd == null) xmlDtd = new XmlDtd(runtime, klazz);
- try {
- XmlDtd clone = (XmlDtd)xmlDtd.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlDtd(runtime, klazz);
- }
- }
- };
-
- public static final ObjectAllocator XML_ELEMENT_ALLOCATOR = new ObjectAllocator() {
- private XmlElement xmlElement = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlElement == null) xmlElement = new XmlElement(runtime, klazz);
- try {
- XmlElement clone = (XmlElement)xmlElement.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlElement(runtime, klazz);
- }
- }
- };
-
- public static ObjectAllocator XML_ELEMENT_DECL_ALLOCATOR = new ObjectAllocator() {
- private XmlElementDecl xmlElementDecl = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlElementDecl == null) xmlElementDecl = new XmlElementDecl(runtime, klazz);
- try {
- XmlElementDecl clone = (XmlElementDecl)xmlElementDecl.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlElementDecl(runtime, klazz);
- }
- }
- };
-
- public static ObjectAllocator XML_ENTITY_REFERENCE_ALLOCATOR = new ObjectAllocator() {
- private XmlEntityReference xmlEntityRef = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlEntityRef == null) xmlEntityRef = new XmlEntityReference(runtime, klazz);
- try {
- XmlEntityReference clone = (XmlEntityReference)xmlEntityRef.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlEntityReference(runtime, klazz);
- }
- }
- };
-
- public static final ObjectAllocator XML_NAMESPACE_ALLOCATOR = new ObjectAllocator() {
- private XmlNamespace xmlNamespace = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlNamespace == null) xmlNamespace = new XmlNamespace(runtime, klazz);
- try {
- XmlNamespace clone = (XmlNamespace) xmlNamespace.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlNamespace(runtime, klazz);
- }
- }
- };
-
- public static final ObjectAllocator XML_NODE_ALLOCATOR = new ObjectAllocator() {
- private XmlNode xmlNode = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlNode == null) xmlNode = new XmlNode(runtime, klazz);
- try {
- XmlNode clone = (XmlNode) xmlNode.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlNode(runtime, klazz);
- }
- }
- };
-
- public static final ObjectAllocator XML_NODESET_ALLOCATOR = new ObjectAllocator() {
- private XmlNodeSet xmlNodeSet = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlNodeSet == null) xmlNodeSet = new XmlNodeSet(runtime, klazz);
- try {
- XmlNodeSet clone = (XmlNodeSet) xmlNodeSet.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlNodeSet(runtime, klazz);
- }
- }
- };
-
- public static ObjectAllocator XML_PROCESSING_INSTRUCTION_ALLOCATOR = new ObjectAllocator() {
- private XmlProcessingInstruction xmlProcessingInstruction = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlProcessingInstruction == null) xmlProcessingInstruction = new XmlProcessingInstruction(runtime, klazz);
- try {
- XmlProcessingInstruction clone = (XmlProcessingInstruction)xmlProcessingInstruction.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlProcessingInstruction(runtime, klazz);
- }
- }
- };
-
- public static ObjectAllocator XML_READER_ALLOCATOR = new ObjectAllocator() {
- private XmlReader xmlReader = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlReader == null) xmlReader = new XmlReader(runtime, klazz);
- try {
- XmlReader clone = (XmlReader) xmlReader.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- xmlReader = new XmlReader(runtime, klazz);
- return xmlReader;
- }
- }
- };
-
- private static ObjectAllocator XML_ATTRIBUTE_DECL_ALLOCATOR = new ObjectAllocator() {
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- return new XmlAttributeDecl(runtime, klazz);
- }
- };
-
- private static ObjectAllocator XML_ENTITY_DECL_ALLOCATOR = new ObjectAllocator() {
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- return new XmlEntityDecl(runtime, klazz);
- }
- };
-
- private static ObjectAllocator XML_ELEMENT_CONTENT_ALLOCATOR = new ObjectAllocator() {
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- throw runtime.newNotImplementedError("not implemented");
- }
- };
-
- public static final ObjectAllocator XML_RELAXNG_ALLOCATOR = new ObjectAllocator() {
- private XmlRelaxng xmlRelaxng = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlRelaxng == null) xmlRelaxng = new XmlRelaxng(runtime, klazz);
- try {
- XmlRelaxng clone = (XmlRelaxng) xmlRelaxng.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlRelaxng(runtime, klazz);
- }
- }
- };
-
- public static final ObjectAllocator XML_SAXPARSER_CONTEXT_ALLOCATOR = new ObjectAllocator() {
- private XmlSaxParserContext xmlSaxParserContext = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlSaxParserContext == null) xmlSaxParserContext = new XmlSaxParserContext(runtime, klazz);
- try {
- XmlSaxParserContext clone = (XmlSaxParserContext) xmlSaxParserContext.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlSaxParserContext(runtime, klazz);
- }
- }
- };
-
- private static final ObjectAllocator XML_SAXPUSHPARSER_ALLOCATOR = new ObjectAllocator() {
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- return new XmlSaxPushParser(runtime, klazz);
- }
- };
-
- private static final ObjectAllocator HTML_SAXPUSHPARSER_ALLOCATOR = new ObjectAllocator() {
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- return new HtmlSaxPushParser(runtime, klazz);
- }
- };
-
- public static final ObjectAllocator XML_SCHEMA_ALLOCATOR = new ObjectAllocator() {
- private XmlSchema xmlSchema = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlSchema == null) xmlSchema = new XmlSchema(runtime, klazz);
- try {
- XmlSchema clone = (XmlSchema) xmlSchema.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlSchema(runtime, klazz);
- }
- }
- };
-
- public static final ObjectAllocator XML_SYNTAXERROR_ALLOCATOR = new ObjectAllocator() {
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- return new XmlSyntaxError(runtime, klazz);
- }
- };
-
- public static final ObjectAllocator XML_TEXT_ALLOCATOR = new ObjectAllocator() {
- private XmlText xmlText = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xmlText == null) xmlText = new XmlText(runtime, klazz);
- try {
- XmlText clone = (XmlText) xmlText.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlText(runtime, klazz);
- }
- }
- };
-
- public static final ObjectAllocator XML_XPATHCONTEXT_ALLOCATOR = new ObjectAllocator() {
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- return new XmlXpathContext(runtime, klazz);
- }
- };
-
- public static ObjectAllocator XSLT_STYLESHEET_ALLOCATOR = new ObjectAllocator() {
- private XsltStylesheet xsltStylesheet = null;
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
- if (xsltStylesheet == null) xsltStylesheet = new XsltStylesheet(runtime, klazz);
- try {
- XsltStylesheet clone = (XsltStylesheet) xsltStylesheet.clone();
- clone.setMetaClass(klazz);
- return clone;
- } catch (CloneNotSupportedException e) {
- return new XmlText(runtime, klazz);
- }
- }
- };
+ public static final ObjectAllocator XML_XPATHCONTEXT_ALLOCATOR = new ObjectAllocator()
+ {
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ return new XmlXpathContext(runtime, klazz);
+ }
+ };
+
+ public static ObjectAllocator XSLT_STYLESHEET_ALLOCATOR = new ObjectAllocator()
+ {
+ private XsltStylesheet xsltStylesheet = null;
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
+ if (xsltStylesheet == null) { xsltStylesheet = new XsltStylesheet(runtime, klazz); }
+ try {
+ XsltStylesheet clone = (XsltStylesheet) xsltStylesheet.clone();
+ clone.setMetaClass(klazz);
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return new XmlText(runtime, klazz);
+ }
+ }
+ };
}
diff --git a/ext/java/nokogiri/XmlAttr.java b/ext/java/nokogiri/XmlAttr.java
index 06235d930d..029f6f407f 100644
--- a/ext/java/nokogiri/XmlAttr.java
+++ b/ext/java/nokogiri/XmlAttr.java
@@ -1,35 +1,3 @@
-/**
- * (The MIT License)
- *
- * Copyright (c) 2008 - 2012:
- *
- * * {Aaron Patterson}[http://tenderlovemaking.com]
- * * {Mike Dalessio}[http://mike.daless.io]
- * * {Charles Nutter}[http://blog.headius.com]
- * * {Sergio Arbeo}[http://www.serabe.com]
- * * {Patrick Mahoney}[http://polycrystal.org]
- * * {Yoko Harada}[http://yokolet.blogspot.com]
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * 'Software'), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
package nokogiri;
import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
@@ -54,116 +22,133 @@
* @author sergio
* @author Yoko Harada
*/
-
-@JRubyClass(name="Nokogiri::XML::Attr", parent="Nokogiri::XML::Node")
-public class XmlAttr extends XmlNode {
-
- public static final String[] HTML_BOOLEAN_ATTRS = {
- "checked", "compact", "declare", "defer", "disabled", "ismap",
- "multiple", "nohref", "noresize", "noshade", "nowrap", "readonly",
- "selected"
- };
-
- public XmlAttr(Ruby ruby, Node attr){
- super(ruby, getNokogiriClass(ruby, "Nokogiri::XML::Attr"), attr);
+@JRubyClass(name = "Nokogiri::XML::Attr", parent = "Nokogiri::XML::Node")
+public class XmlAttr extends XmlNode
+{
+ private static final long serialVersionUID = 1L;
+
+ public static final String[] HTML_BOOLEAN_ATTRS = {
+ "checked", "compact", "declare", "defer", "disabled", "ismap",
+ "multiple", "nohref", "noresize", "noshade", "nowrap", "readonly",
+ "selected"
+ };
+
+ public
+ XmlAttr(Ruby ruby, Node attr)
+ {
+ super(ruby, getNokogiriClass(ruby, "Nokogiri::XML::Attr"), attr);
+ }
+
+ public
+ XmlAttr(Ruby ruby, RubyClass rubyClass)
+ {
+ super(ruby, rubyClass);
+ }
+
+ public
+ XmlAttr(Ruby ruby, RubyClass rubyClass, Node attr)
+ {
+ super(ruby, rubyClass, attr);
+ }
+
+ @Override
+ protected void
+ init(ThreadContext context, IRubyObject[] args)
+ {
+ if (args.length < 2) {
+ throw context.runtime.newArgumentError(args.length, 2);
}
- public XmlAttr(Ruby ruby, RubyClass rubyClass) {
- super(ruby, rubyClass);
- }
+ IRubyObject doc = args[0];
+ IRubyObject content = args[1];
- public XmlAttr(Ruby ruby, RubyClass rubyClass, Node attr){
- super(ruby, rubyClass, attr);
+ if (!(doc instanceof XmlDocument)) {
+ throw context.runtime.newArgumentError("document must be an instance of Nokogiri::XML::Document");
}
- @Override
- protected void init(ThreadContext context, IRubyObject[] args) {
- if (args.length < 2) {
- throw getRuntime().newArgumentError(args.length, 2);
- }
-
- IRubyObject doc = args[0];
- IRubyObject content = args[1];
-
- if(!(doc instanceof XmlDocument)) {
- final String msg =
- "document must be an instance of Nokogiri::XML::Document";
- throw getRuntime().newArgumentError(msg);
- }
-
- XmlDocument xmlDoc = (XmlDocument)doc;
- String str = rubyStringToString(content);
- Node attr = xmlDoc.getDocument().createAttribute(str);
- setNode(context, attr);
+ XmlDocument xmlDoc = (XmlDocument)doc;
+ String str = rubyStringToString(content);
+ Node attr = xmlDoc.getDocument().createAttribute(str);
+ setNode(context.runtime, attr);
+ }
+
+
+ // this method is called from XmlNode.setNode()
+ // if the node is attribute, and its name has prefix "xml"
+ // the default namespace should be registered for this attribute
+ void
+ setNamespaceIfNecessary(Ruby runtime)
+ {
+ if ("xml".equals(node.getPrefix())) {
+ XmlNamespace.createDefaultNamespace(runtime, node);
}
-
-
- // this method is called from XmlNode.setNode()
- // if the node is attribute, and its name has prefix "xml"
- // the default namespace should be registered for this attribute
- void setNamespaceIfNecessary(Ruby runtime) {
- if ("xml".equals(node.getPrefix())) {
- XmlNamespace.createDefaultNamespace(runtime, node);
- }
+ }
+
+ @Override
+ @JRubyMethod(name = {"content", "value", "to_s"})
+ public IRubyObject
+ content(ThreadContext context)
+ {
+ if (content != null && !content.isNil()) { return content; }
+ if (node == null) { return context.getRuntime().getNil(); }
+ String attrValue = ((Attr)node).getValue();
+ if (attrValue == null) { return context.getRuntime().getNil(); }
+ return RubyString.newString(context.getRuntime(), attrValue);
+ }
+
+ @JRubyMethod(name = {"value=", "content="})
+ public IRubyObject
+ value_set(ThreadContext context, IRubyObject content)
+ {
+ Attr attr = (Attr) node;
+ if (content != null && !content.isNil()) {
+ attr.setValue(rubyStringToString(XmlNode.encode_special_chars(context, content)));
}
-
- private boolean isHtmlBooleanAttr() {
- String name = node.getNodeName().toLowerCase();
-
- for(String s : HTML_BOOLEAN_ATTRS) {
- if(s.equals(name)) return true;
- }
-
- return false;
- }
-
- @Override
- @JRubyMethod(name = {"content", "value", "to_s"})
- public IRubyObject content(ThreadContext context) {
- if (content != null && !content.isNil()) return content;
- if (node == null) return context.getRuntime().getNil();
- String attrValue = ((Attr)node).getValue();
- if (attrValue == null) return context.getRuntime().getNil();
- return RubyString.newString(context.getRuntime(), attrValue);
- }
-
- @JRubyMethod(name = {"value=", "content="})
- public IRubyObject value_set(ThreadContext context, IRubyObject content){
- Attr attr = (Attr) node;
- if (content != null && !content.isNil()) {
- attr.setValue(rubyStringToString(XmlNode.encode_special_chars(context, content)));
- }
- setContent(content);
- return content;
- }
-
- @Override
- protected IRubyObject getNodeName(ThreadContext context) {
- if (name != null) return name;
- String attrName = ((Attr)node).getName();
- if (!(doc instanceof HtmlDocument) && node.getNamespaceURI() != null) {
- attrName = NokogiriHelpers.getLocalPart(attrName);
- }
- return attrName == null ? context.getRuntime().getNil() : RubyString.newString(context.getRuntime(), attrName);
+ setContent(content);
+ return content;
+ }
+
+ @Override
+ protected IRubyObject
+ getNodeName(ThreadContext context)
+ {
+ if (name != null) { return name; }
+
+ String attrName = ((Attr) node).getName();
+ if (attrName == null) { return context.nil; }
+
+ if (node.getNamespaceURI() != null && !(document(context.runtime) instanceof Html4Document)) {
+ attrName = NokogiriHelpers.getLocalPart(attrName);
+ if (attrName == null) { return context.nil; }
}
- @Override
- public void accept(ThreadContext context, SaveContextVisitor visitor) {
- visitor.enter((Attr)node);
- visitor.leave((Attr)node);
- }
-
- private boolean isHtml(ThreadContext context) {
- return document(context).getMetaClass().isKindOfModule(getNokogiriClass(context.getRuntime(), "Nokogiri::HTML::Document"));
- }
-
- @Override
- public IRubyObject unlink(ThreadContext context) {
- Attr attr = (Attr) node;
- Element parent = attr.getOwnerElement();
- parent.removeAttributeNode(attr);
-
- return this;
- }
+ return name = RubyString.newString(context.runtime, attrName);
+ }
+
+ @Override
+ public void
+ accept(ThreadContext context, SaveContextVisitor visitor)
+ {
+ visitor.enter((Attr)node);
+ visitor.leave((Attr)node);
+ }
+
+ private boolean
+ isHtml(ThreadContext context)
+ {
+ return document(context).getMetaClass().isKindOfModule(getNokogiriClass(context.getRuntime(),
+ "Nokogiri::HTML4::Document"));
+ }
+
+ @Override
+ public IRubyObject
+ unlink(ThreadContext context)
+ {
+ Attr attr = (Attr) node;
+ Element parent = attr.getOwnerElement();
+ parent.removeAttributeNode(attr);
+
+ return this;
+ }
}
diff --git a/ext/java/nokogiri/XmlAttributeDecl.java b/ext/java/nokogiri/XmlAttributeDecl.java
index cca3cee25e..242fc804fd 100644
--- a/ext/java/nokogiri/XmlAttributeDecl.java
+++ b/ext/java/nokogiri/XmlAttributeDecl.java
@@ -1,35 +1,3 @@
-/**
- * (The MIT License)
- *
- * Copyright (c) 2008 - 2011:
- *
- * * {Aaron Patterson}[http://tenderlovemaking.com]
- * * {Mike Dalessio}[http://mike.daless.io]
- * * {Charles Nutter}[http://blog.headius.com]
- * * {Sergio Arbeo}[http://www.serabe.com]
- * * {Patrick Mahoney}[http://polycrystal.org]
- * * {Yoko Harada}[http://yokolet.blogspot.com]
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * 'Software'), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
package nokogiri;
import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
@@ -49,82 +17,103 @@
*
* @author Patrick Mahoney
*/
-@JRubyClass(name="Nokogiri::XML::AttributeDecl", parent="Nokogiri::XML::Node")
-public class XmlAttributeDecl extends XmlNode {
-
- public XmlAttributeDecl(Ruby ruby, RubyClass klass) {
- super(ruby, klass);
- throw ruby.newRuntimeError("node required");
- }
-
- /**
- * Initialize based on an attributeDecl node from a NekoDTD parsed
- * DTD.
- *
- * Internally, XmlAttributeDecl combines these into a single node.
- */
- public XmlAttributeDecl(Ruby ruby, RubyClass klass, Node attrDeclNode) {
- super(ruby, klass, attrDeclNode);
- }
-
- public static IRubyObject create(ThreadContext context, Node attrDeclNode) {
- XmlAttributeDecl self =
- new XmlAttributeDecl(context.getRuntime(),
- getNokogiriClass(context.getRuntime(), "Nokogiri::XML::AttributeDecl"),
- attrDeclNode);
- return self;
- }
-
- @Override
- @JRubyMethod
- public IRubyObject node_name(ThreadContext context) {
- return attribute_name(context);
- }
-
- @Override
- @JRubyMethod(name = "node_name=")
- public IRubyObject node_name_set(ThreadContext context, IRubyObject name) {
- throw context.getRuntime()
- .newRuntimeError("cannot change name of DTD decl");
- }
-
- public IRubyObject element_name(ThreadContext context) {
- return getAttribute(context, "ename");
- }
-
- public IRubyObject attribute_name(ThreadContext context) {
- return getAttribute(context, "aname");
- }
-
- @JRubyMethod
- public IRubyObject attribute_type(ThreadContext context) {
- return getAttribute(context, "atype");
+@JRubyClass(name = "Nokogiri::XML::AttributeDecl", parent = "Nokogiri::XML::Node")
+public class XmlAttributeDecl extends XmlNode
+{
+ private static final long serialVersionUID = 1L;
+
+ public
+ XmlAttributeDecl(Ruby ruby, RubyClass klass)
+ {
+ super(ruby, klass);
+ throw ruby.newRuntimeError("node required");
+ }
+
+ /**
+ * Initialize based on an attributeDecl node from a NekoDTD parsed
+ * DTD.
+ *
+ * Internally, XmlAttributeDecl combines these into a single node.
+ */
+ public
+ XmlAttributeDecl(Ruby ruby, RubyClass klass, Node attrDeclNode)
+ {
+ super(ruby, klass, attrDeclNode);
+ }
+
+ static XmlAttributeDecl
+ create(ThreadContext context, Node attrDeclNode)
+ {
+ return new XmlAttributeDecl(context.runtime,
+ getNokogiriClass(context.runtime, "Nokogiri::XML::AttributeDecl"),
+ attrDeclNode
+ );
+ }
+
+ @Override
+ @JRubyMethod
+ public IRubyObject
+ node_name(ThreadContext context)
+ {
+ return attribute_name(context);
+ }
+
+ @Override
+ @JRubyMethod(name = "node_name=")
+ public IRubyObject
+ node_name_set(ThreadContext context, IRubyObject name)
+ {
+ throw context.runtime.newRuntimeError("cannot change name of DTD decl");
+ }
+
+ public IRubyObject
+ element_name(ThreadContext context)
+ {
+ return getAttribute(context, "ename");
+ }
+
+ public IRubyObject
+ attribute_name(ThreadContext context)
+ {
+ return getAttribute(context, "aname");
+ }
+
+ @JRubyMethod
+ public IRubyObject
+ attribute_type(ThreadContext context)
+ {
+ return getAttribute(context, "atype");
+ }
+
+ @JRubyMethod(name = "default")
+ public IRubyObject
+ default_value(ThreadContext context)
+ {
+ return getAttribute(context, "default");
+ }
+
+ /**
+ * FIXME: will enumerations all be of the simple (val1|val2|val3)
+ * type string?
+ */
+ @JRubyMethod
+ public IRubyObject
+ enumeration(ThreadContext context)
+ {
+ final String atype = ((Element) node).getAttribute("atype");
+
+ if (atype != null && atype.length() != 0 && atype.charAt(0) == '(') {
+ // removed enclosing parens
+ String valueStr = atype.substring(1, atype.length() - 1);
+ String[] values = valueStr.split("\\|");
+ RubyArray> enumVals = RubyArray.newArray(context.runtime, values.length);
+ for (int i = 0; i < values.length; i++) {
+ enumVals.append(context.runtime.newString(values[i]));
+ }
+ return enumVals;
}
- @JRubyMethod(name="default")
- public IRubyObject default_value(ThreadContext context) {
- return getAttribute(context, "default");
- }
-
- /**
- * FIXME: will enumerations all be of the simple (val1|val2|val3)
- * type string?
- */
- @JRubyMethod
- public IRubyObject enumeration(ThreadContext context) {
- RubyArray enumVals = RubyArray.newArray(context.getRuntime());
- String atype = ((Element)node).getAttribute("atype");
-
- if (atype != null && atype.length() != 0 && atype.charAt(0) == '(') {
- // removed enclosing parens
- String valueStr = atype.substring(1, atype.length() - 1);
- String[] values = valueStr.split("\\|");
- for (int i = 0; i < values.length; i++) {
- enumVals.append(context.getRuntime().newString(values[i]));
- }
- }
-
- return enumVals;
- }
+ return context.runtime.newEmptyArray();
+ }
}
diff --git a/ext/java/nokogiri/XmlCdata.java b/ext/java/nokogiri/XmlCdata.java
index 0980378db3..31b8f420c6 100644
--- a/ext/java/nokogiri/XmlCdata.java
+++ b/ext/java/nokogiri/XmlCdata.java
@@ -1,35 +1,3 @@
-/**
- * (The MIT License)
- *
- * Copyright (c) 2008 - 2011:
- *
- * * {Aaron Patterson}[http://tenderlovemaking.com]
- * * {Mike Dalessio}[http://mike.daless.io]
- * * {Charles Nutter}[http://blog.headius.com]
- * * {Sergio Arbeo}[http://www.serabe.com]
- * * {Patrick Mahoney}[http://polycrystal.org]
- * * {Yoko Harada}[http://yokolet.blogspot.com]
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * 'Software'), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
package nokogiri;
import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
@@ -51,33 +19,42 @@
* @author sergio
* @author Yoko Harada
*/
-
-@JRubyClass(name="Nokogiri::XML::CDATA", parent="Nokogiri::XML::Text")
-public class XmlCdata extends XmlText {
- public XmlCdata(Ruby ruby, RubyClass rubyClass) {
- super(ruby, rubyClass);
- }
-
- public XmlCdata(Ruby ruby, RubyClass rubyClass, Node node) {
- super(ruby, rubyClass, node);
- }
-
- @Override
- protected void init(ThreadContext context, IRubyObject[] args) {
- if (args.length < 2) {
- throw getRuntime().newArgumentError(args.length, 2);
- }
- IRubyObject doc = args[0];
- content = args[1];
- XmlDocument xmlDoc =(XmlDocument) ((XmlNode) doc).document(context);
- Document document = xmlDoc.getDocument();
- Node node = document.createCDATASection((content.isNil()) ? null : rubyStringToString(content));
- setNode(context, node);
- }
-
- @Override
- public void accept(ThreadContext context, SaveContextVisitor visitor) {
- visitor.enter((CDATASection)node);
- visitor.leave((CDATASection)node);
+@JRubyClass(name = "Nokogiri::XML::CDATA", parent = "Nokogiri::XML::Text")
+public class XmlCdata extends XmlText
+{
+ private static final long serialVersionUID = 1L;
+
+ public
+ XmlCdata(Ruby ruby, RubyClass rubyClass)
+ {
+ super(ruby, rubyClass);
+ }
+
+ public
+ XmlCdata(Ruby ruby, RubyClass rubyClass, Node node)
+ {
+ super(ruby, rubyClass, node);
+ }
+
+ @Override
+ protected void
+ init(ThreadContext context, IRubyObject[] args)
+ {
+ if (args.length < 2) {
+ throw getRuntime().newArgumentError(args.length, 2);
}
+ IRubyObject doc = args[0];
+ content = args[1];
+ Document document = ((XmlNode) doc).getOwnerDocument();
+ Node node = document.createCDATASection(rubyStringToString(content));
+ setNode(context.runtime, node);
+ }
+
+ @Override
+ public void
+ accept(ThreadContext context, SaveContextVisitor visitor)
+ {
+ visitor.enter((CDATASection)node);
+ visitor.leave((CDATASection)node);
+ }
}
diff --git a/ext/java/nokogiri/XmlComment.java b/ext/java/nokogiri/XmlComment.java
index 7f6445fe29..f77a91e366 100644
--- a/ext/java/nokogiri/XmlComment.java
+++ b/ext/java/nokogiri/XmlComment.java
@@ -1,35 +1,3 @@
-/**
- * (The MIT License)
- *
- * Copyright (c) 2008 - 2012:
- *
- * * {Aaron Patterson}[http://tenderlovemaking.com]
- * * {Mike Dalessio}[http://mike.daless.io]
- * * {Charles Nutter}[http://blog.headius.com]
- * * {Sergio Arbeo}[http://www.serabe.com]
- * * {Patrick Mahoney}[http://polycrystal.org]
- * * {Yoko Harada}[http://yokolet.blogspot.com]
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * 'Software'), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
package nokogiri;
import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
@@ -50,48 +18,60 @@
* @author sergio
* @author Yoko Harada
*/
+@JRubyClass(name = "Nokogiri::XML::Comment", parent = "Nokogiri::XML::CharacterData")
+public class XmlComment extends XmlNode
+{
+ private static final long serialVersionUID = 1L;
-@JRubyClass(name="Nokogiri::XML::Comment", parent="Nokogiri::XML::CharacterData")
-public class XmlComment extends XmlNode {
- public XmlComment(Ruby ruby, RubyClass rubyClass, Node node) {
- super(ruby, rubyClass, node);
- }
+ public
+ XmlComment(Ruby ruby, RubyClass rubyClass, Node node)
+ {
+ super(ruby, rubyClass, node);
+ }
+
+ public
+ XmlComment(Ruby runtime, RubyClass klass)
+ {
+ super(runtime, klass);
+ }
- public XmlComment(Ruby runtime, RubyClass klass) {
- super(runtime, klass);
+ @Override
+ protected void
+ init(ThreadContext context, IRubyObject[] args)
+ {
+ if (args.length < 2) {
+ throw getRuntime().newArgumentError(args.length, 2);
}
- @Override
- protected void init(ThreadContext context, IRubyObject[] args) {
- if (args.length < 2)
- throw getRuntime().newArgumentError(args.length, 2);
+ IRubyObject doc = args[0];
+ IRubyObject text = args[1];
- IRubyObject doc = args[0];
- IRubyObject text = args[1];
+ XmlDocument xmlDoc;
+ if (doc instanceof XmlDocument) {
+ xmlDoc = (XmlDocument) doc;
- XmlDocument xmlDoc;
- if (doc instanceof XmlDocument) {
- xmlDoc = (XmlDocument) doc;
-
- } else if (doc instanceof XmlNode) {
- XmlNode xmlNode = (XmlNode) doc;
- xmlDoc = (XmlDocument)xmlNode.document(context);
- } else {
- throw getRuntime().newArgumentError("first argument must be a XML::Document or XML::Node");
- }
- if (xmlDoc != null) {
- Document document = xmlDoc.getDocument();
- Node node = document.createComment(rubyStringToString(text));
- setNode(context, node);
- }
+ } else if (doc instanceof XmlNode) {
+ XmlNode xmlNode = (XmlNode) doc;
+ xmlDoc = (XmlDocument)xmlNode.document(context);
+ } else {
+ throw getRuntime().newArgumentError("first argument must be a XML::Document or XML::Node");
}
+ if (xmlDoc != null) {
+ Document document = xmlDoc.getDocument();
+ Node node = document.createComment(rubyStringToString(text));
+ setNode(context.runtime, node);
+ }
+ }
- @Override
- public boolean isComment() { return true; }
+ @Override
+ public boolean
+ isComment() { return true; }
- @Override
- public void accept(ThreadContext context, SaveContextVisitor visitor) {
- visitor.enter((Comment)node);
- visitor.leave((Comment)node);
- }
+ @Override
+ public void
+ accept(ThreadContext context, SaveContextVisitor visitor)
+ {
+ visitor.enter((Comment)node);
+ visitor.leave((Comment)node);
+ }
}
diff --git a/ext/java/nokogiri/XmlDocument.java b/ext/java/nokogiri/XmlDocument.java
index 152d2e9efd..3141ae28c4 100644
--- a/ext/java/nokogiri/XmlDocument.java
+++ b/ext/java/nokogiri/XmlDocument.java
@@ -1,35 +1,3 @@
-/**
- * (The MIT License)
- *
- * Copyright (c) 2008 - 2014:
- *
- * * {Aaron Patterson}[http://tenderlovemaking.com]
- * * {Mike Dalessio}[http://mike.daless.io]
- * * {Charles Nutter}[http://blog.headius.com]
- * * {Sergio Arbeo}[http://www.serabe.com]
- * * {Patrick Mahoney}[http://polycrystal.org]
- * * {Yoko Harada}[http://yokolet.blogspot.com]
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * 'Software'), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
package nokogiri;
import static nokogiri.internals.NokogiriHelpers.clearXpathContext;
@@ -39,25 +7,28 @@
import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
import static nokogiri.internals.NokogiriHelpers.stringOrNil;
-import java.io.UnsupportedEncodingException;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
+import org.jcodings.specific.USASCIIEncoding;
+import org.jcodings.specific.UTF8Encoding;
import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyClass;
import org.jruby.RubyFixnum;
-import org.jruby.RubyNil;
+import org.jruby.RubyString;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
+import org.jruby.exceptions.RaiseException;
import org.jruby.javasupport.JavaUtil;
-import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.util.ByteList;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
@@ -80,581 +51,655 @@
* @author Yoko Harada
* @author John Shahid
*/
-
-@JRubyClass(name="Nokogiri::XML::Document", parent="Nokogiri::XML::Node")
-public class XmlDocument extends XmlNode {
- private NokogiriNamespaceCache nsCache;
-
- /* UserData keys for storing extra info in the document node. */
- public final static String DTD_RAW_DOCUMENT = "DTD_RAW_DOCUMENT";
- public final static String DTD_INTERNAL_SUBSET = "DTD_INTERNAL_SUBSET";
- public final static String DTD_EXTERNAL_SUBSET = "DTD_EXTERNAL_SUBSET";
-
- /* DocumentBuilderFactory implementation class name. This needs to set a classloader into it.
- * Setting an appropriate classloader resolves issue 380.
- */
- private static final String DOCUMENTBUILDERFACTORY_IMPLE_NAME = "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl";
-
- private static boolean substituteEntities = false;
- private static boolean loadExternalSubset = false; // TODO: Verify this.
-
- /** cache variables */
- protected IRubyObject encoding = null;
- protected IRubyObject url = null;
-
- public XmlDocument(Ruby ruby, RubyClass klazz) {
- super(ruby, klazz, createNewDocument());
- }
-
- public XmlDocument(Ruby ruby, Document document) {
- this(ruby, getNokogiriClass(ruby, "Nokogiri::XML::Document"), document);
- }
-
- public XmlDocument(Ruby ruby, RubyClass klass, Document document) {
- super(ruby, klass, document);
- initializeNamespaceCacheIfNecessary();
- createAndCacheNamespaces(ruby, document.getDocumentElement());
- stabilizeTextContent(document);
- setInstanceVariable("@decorators", ruby.getNil());
- }
-
- public void setDocumentNode(ThreadContext context, Node node) {
- super.setNode(context, node);
- initializeNamespaceCacheIfNecessary();
- Ruby runtime = context.getRuntime();
- if (node != null) {
- Document document = (Document)node;
- stabilizeTextContent(document);
- createAndCacheNamespaces(runtime, document.getDocumentElement());
+@JRubyClass(name = "Nokogiri::XML::Document", parent = "Nokogiri::XML::Node")
+public class XmlDocument extends XmlNode
+{
+ private static final long serialVersionUID = 1L;
+
+ private NokogiriNamespaceCache nsCache;
+
+ /* UserData keys for storing extra info in the document node. */
+ public final static String DTD_RAW_DOCUMENT = "DTD_RAW_DOCUMENT";
+ public final static String DTD_INTERNAL_SUBSET = "DTD_INTERNAL_SUBSET";
+ public final static String DTD_EXTERNAL_SUBSET = "DTD_EXTERNAL_SUBSET";
+
+ /* DocumentBuilderFactory implementation class name. This needs to set a classloader into it.
+ * Setting an appropriate classloader resolves issue 380.
+ */
+ private static final String DOCUMENTBUILDERFACTORY_IMPLE_NAME = "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl";
+
+ private static final ByteList DOCUMENT = ByteList.create("document");
+ static { DOCUMENT.setEncoding(USASCIIEncoding.INSTANCE); }
+
+ private static boolean substituteEntities = false;
+ private static boolean loadExternalSubset = false; // TODO: Verify this.
+
+ /** cache variables */
+ protected IRubyObject encoding;
+ protected IRubyObject url;
+
+ public
+ XmlDocument(Ruby runtime, RubyClass klazz)
+ {
+ super(runtime, klazz, createNewDocument(runtime));
+ }
+
+ public
+ XmlDocument(Ruby runtime, Document document)
+ {
+ this(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Document"), document);
+ }
+
+ public
+ XmlDocument(Ruby runtime, RubyClass klass, Document document)
+ {
+ super(runtime, klass, document);
+ init(runtime, document);
+ }
+
+ void
+ init(Ruby runtime, Document document)
+ {
+ stabilizeTextContent(document);
+ if (document.getDocumentElement() != null) {
+ createAndCacheNamespaces(runtime, document.getDocumentElement());
+ }
+ setInstanceVariable("@decorators", runtime.getNil());
+ }
+
+ public final void
+ setDocumentNode(Ruby runtime, Document node)
+ {
+ super.setNode(runtime, node);
+ if (node != null) { init(runtime, node); }
+ else { setInstanceVariable("@decorators", runtime.getNil()); }
+ }
+
+ public void
+ setEncoding(IRubyObject encoding)
+ {
+ this.encoding = encoding;
+ }
+
+ public IRubyObject
+ getEncoding()
+ {
+ return encoding;
+ }
+
+ // not sure, but like attribute values, text value will be lost
+ // unless it is referred once before this document is used.
+ // this seems to happen only when the fragment is parsed from Node#in_context.
+ protected static void
+ stabilizeTextContent(Document document)
+ {
+ if (document.getDocumentElement() != null) { document.getDocumentElement().getTextContent(); }
+ }
+
+ private static void
+ createAndCacheNamespaces(Ruby runtime, Node node)
+ {
+ if (node.hasAttributes()) {
+ NamedNodeMap nodeMap = node.getAttributes();
+ for (int i = 0; i < nodeMap.getLength(); i++) {
+ Node n = nodeMap.item(i);
+ if (n instanceof Attr) {
+ Attr attr = (Attr) n;
+ stabilizeAttr(attr);
+ if (isNamespace(attr.getName())) {
+ // create and cache
+ XmlNamespace.createFromAttr(runtime, attr);
+ }
}
- setInstanceVariable("@decorators", runtime.getNil());
- }
-
- public void setEncoding(IRubyObject encoding) {
- this.encoding = encoding;
- }
-
- public IRubyObject getEncoding() {
- return encoding;
- }
-
- // not sure, but like attribute values, text value will be lost
- // unless it is referred once before this document is used.
- // this seems to happen only when the fragment is parsed from Node#in_context.
- protected void stabilizeTextContent(Document document) {
- if (document.getDocumentElement() != null) document.getDocumentElement().getTextContent();
- }
-
- private void createAndCacheNamespaces(Ruby ruby, Node node) {
- if (node == null) return;
- if (node.hasAttributes()) {
- NamedNodeMap nodeMap = node.getAttributes();
- for (int i=0; i 0 && !(args[0].isNil())) {
- mode = RubyFixnum.fix2int(args[0]);
- }
- if (args.length > 1 ) {
- if (!args[1].isNil() && !(args[1] instanceof List)) {
- throw context.getRuntime().newTypeError("Expected array");
- }
- if (!args[1].isNil()) {
- inclusive_namespace = ((RubyArray)args[1])
- .join(context, context.getRuntime().newString(" "))
- .asString()
- .asJavaString(); // OMG I wish I knew JRuby better, this is ugly
- }
- }
- if (args.length > 2) {
- with_comments = args[2].isTrue();
- }
- String algorithmURI = null;
- switch(mode) {
- case 0: // XML_C14N_1_0
- if (with_comments) algorithmURI = Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS;
- else algorithmURI = Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS;
- break;
- case 1: // XML_C14N_EXCLUSIVE_1_0
- if (with_comments) algorithmURI = Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS;
- else algorithmURI = Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
- break;
- case 2: // XML_C14N_1_1 = 2
- if (with_comments) algorithmURI = Canonicalizer.ALGO_ID_C14N11_WITH_COMMENTS;
- else algorithmURI = Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS;
- }
- try {
- Canonicalizer canonicalizer = Canonicalizer.getInstance(algorithmURI);
- XmlNode startingNode = getStartingNode(block);
- byte[] result;
- CanonicalFilter filter = new CanonicalFilter(context, block);
- if (inclusive_namespace == null) {
- result = canonicalizer.canonicalizeSubtree(startingNode.getNode(), filter);
- } else {
- result = canonicalizer.canonicalizeSubtree(startingNode.getNode(), inclusive_namespace, filter);
- }
- String resultString = new String(result, "UTF-8");
- return stringOrNil(context.getRuntime(), resultString);
- } catch (CanonicalizationException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (UnsupportedEncodingException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return context.getRuntime().getNil();
- }
-
- private XmlNode getStartingNode(Block block) {
- if (block.isGiven()) {
- if (block.getBinding().getSelf() instanceof XmlNode) {
- return (XmlNode)block.getBinding().getSelf();
- }
- }
- return this;
- }
-
- public void resetNamespaceCache(ThreadContext context) {
- nsCache = new NokogiriNamespaceCache();
- createAndCacheNamespaces(context.getRuntime(), node);
- }
+ dtd = XmlDtd.newEmpty(context.runtime, document, name, publicId, systemId);
+ } else {
+ dtd = context.nil;
+ }
+
+ setInternalSubset(dtd);
+ }
+
+ return dtd;
+ }
+
+ /**
+ * Assumes XmlNode#internal_subset() has returned nil. (i.e. there
+ * is not already an internal subset).
+ */
+ public IRubyObject
+ createInternalSubset(ThreadContext context,
+ IRubyObject name,
+ IRubyObject external_id,
+ IRubyObject system_id)
+ {
+ XmlDtd dtd = XmlDtd.newEmpty(context.runtime, getDocument(), name, external_id, system_id);
+ setInternalSubset(dtd);
+ return dtd;
+ }
+
+ protected void
+ setInternalSubset(IRubyObject data)
+ {
+ node.setUserData(DTD_INTERNAL_SUBSET, data, null);
+ }
+
+ public IRubyObject
+ getExternalSubset(ThreadContext context)
+ {
+ IRubyObject dtd = (IRubyObject) node.getUserData(DTD_EXTERNAL_SUBSET);
+
+ if (dtd == null) { return context.nil; }
+ return dtd;
+ }
+
+ /**
+ * Assumes XmlNode#external_subset() has returned nil. (i.e. there
+ * is not already an external subset).
+ */
+ public IRubyObject
+ createExternalSubset(ThreadContext context,
+ IRubyObject name,
+ IRubyObject external_id,
+ IRubyObject system_id)
+ {
+ XmlDtd dtd = XmlDtd.newEmpty(context.runtime, getDocument(), name, external_id, system_id);
+ setExternalSubset(dtd);
+ return dtd;
+ }
+
+ protected void
+ setExternalSubset(IRubyObject data)
+ {
+ node.setUserData(DTD_EXTERNAL_SUBSET, data, null);
+ }
+
+ @Override
+ public void
+ accept(ThreadContext context, SaveContextVisitor visitor)
+ {
+ Document document = getDocument();
+ visitor.enter(document);
+ NodeList children = document.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ short type = child.getNodeType();
+ if (type == Node.COMMENT_NODE) {
+ XmlComment xmlComment = (XmlComment) getCachedNodeOrCreate(context.runtime, child);
+ xmlComment.accept(context, visitor);
+ } else if (type == Node.DOCUMENT_TYPE_NODE) {
+ XmlDtd xmlDtd = (XmlDtd) getCachedNodeOrCreate(context.runtime, child);
+ xmlDtd.accept(context, visitor);
+ } else if (type == Node.PROCESSING_INSTRUCTION_NODE) {
+ XmlProcessingInstruction xmlProcessingInstruction = (XmlProcessingInstruction) getCachedNodeOrCreate(context.runtime,
+ child);
+ xmlProcessingInstruction.accept(context, visitor);
+ } else if (type == Node.TEXT_NODE) {
+ XmlText xmlText = (XmlText) getCachedNodeOrCreate(context.runtime, child);
+ xmlText.accept(context, visitor);
+ } else if (type == Node.ELEMENT_NODE) {
+ XmlElement xmlElement = (XmlElement) getCachedNodeOrCreate(context.runtime, child);
+ xmlElement.accept(context, visitor);
+ }
+ }
+ visitor.leave(document);
+ }
+
+ @JRubyMethod(meta = true)
+ public static IRubyObject
+ wrap(ThreadContext context, IRubyObject klass, IRubyObject arg)
+ {
+ XmlDocument xmlDocument = new XmlDocument(context.runtime, (RubyClass) klass, arg.toJava(Document.class));
+ Helpers.invoke(context, xmlDocument, "initialize");
+ return xmlDocument;
+ }
+
+ @Deprecated
+ @JRubyMethod(meta = true, visibility = Visibility.PRIVATE)
+ public static IRubyObject
+ wrapJavaDocument(ThreadContext context, IRubyObject klass, IRubyObject arg)
+ {
+ return wrap(context, klass, arg);
+ }
+
+ @Deprecated // default to_java works (due inherited from XmlNode#toJava)
+ @JRubyMethod(visibility = Visibility.PRIVATE)
+ public IRubyObject
+ toJavaDocument(ThreadContext context)
+ {
+ return JavaUtil.convertJavaToUsableRubyObject(context.getRuntime(), node);
+ }
+
+ /* call-seq:
+ * doc.canonicalize(mode=XML_C14N_1_0,inclusive_namespaces=nil,with_comments=false)
+ * doc.canonicalize { |obj, parent| ... }
+ *
+ * Canonicalize a document and return the results. Takes an optional block
+ * that takes two parameters: the +obj+ and that node's +parent+.
+ * The +obj+ will be either a Nokogiri::XML::Node, or a Nokogiri::XML::Namespace
+ * The block must return a non-nil, non-false value if the +obj+ passed in
+ * should be included in the canonicalized document.
+ */
+ @JRubyMethod(optional = 3)
+ public IRubyObject
+ canonicalize(ThreadContext context, IRubyObject[] args, Block block)
+ {
+ int mode = 0;
+ String inclusive_namespace = null;
+ Boolean with_comments = false;
+ if (args.length > 0 && !(args[0].isNil())) {
+ mode = RubyFixnum.fix2int(args[0]);
+ }
+ if (args.length > 1) {
+ if (!args[1].isNil() && !(args[1] instanceof List)) {
+ throw context.runtime.newTypeError("Expected array");
+ }
+ if (!args[1].isNil()) {
+ inclusive_namespace = ((RubyArray)args[1])
+ .join(context, context.runtime.newString(" "))
+ .asString()
+ .asJavaString(); // OMG I wish I knew JRuby better, this is ugly
+ }
+ }
+ if (args.length > 2) {
+ with_comments = args[2].isTrue();
+ }
+ String algorithmURI = null;
+ switch (mode) {
+ case 0: // XML_C14N_1_0
+ if (with_comments) { algorithmURI = Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS; }
+ else { algorithmURI = Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS; }
+ break;
+ case 1: // XML_C14N_EXCLUSIVE_1_0
+ if (with_comments) { algorithmURI = Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS; }
+ else { algorithmURI = Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS; }
+ break;
+ case 2: // XML_C14N_1_1 = 2
+ if (with_comments) { algorithmURI = Canonicalizer.ALGO_ID_C14N11_WITH_COMMENTS; }
+ else { algorithmURI = Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS; }
+ }
+ try {
+ Canonicalizer canonicalizer = Canonicalizer.getInstance(algorithmURI);
+ XmlNode startingNode = getStartingNode(block);
+ byte[] result;
+ CanonicalFilter filter = new CanonicalFilter(context, block);
+ if (inclusive_namespace == null) {
+ result = canonicalizer.canonicalizeSubtree(startingNode.getNode(), filter);
+ } else {
+ result = canonicalizer.canonicalizeSubtree(startingNode.getNode(), inclusive_namespace, filter);
+ }
+ return RubyString.newString(context.runtime, new ByteList(result, UTF8Encoding.INSTANCE));
+ } catch (Exception e) {
+ throw context.getRuntime().newRuntimeError(e.getMessage());
+ }
+ }
+
+ private XmlNode
+ getStartingNode(Block block)
+ {
+ if (block.isGiven()) {
+ IRubyObject boundSelf = block.getBinding().getSelf();
+ if (boundSelf instanceof XmlNode) { return (XmlNode) boundSelf; }
+ }
+ return this;
+ }
+
+ public void
+ resetNamespaceCache(ThreadContext context)
+ {
+ nsCache = new NokogiriNamespaceCache();
+ createAndCacheNamespaces(context.runtime, node);
+ }
}
diff --git a/ext/java/nokogiri/XmlDocumentFragment.java b/ext/java/nokogiri/XmlDocumentFragment.java
index 07df539aa4..36578acad8 100644
--- a/ext/java/nokogiri/XmlDocumentFragment.java
+++ b/ext/java/nokogiri/XmlDocumentFragment.java
@@ -1,35 +1,3 @@
-/**
- * (The MIT License)
- *
- * Copyright (c) 2008 - 2011:
- *
- * * {Aaron Patterson}[http://tenderlovemaking.com]
- * * {Mike Dalessio}[http://mike.daless.io]
- * * {Charles Nutter}[http://blog.headius.com]
- * * {Sergio Arbeo}[http://www.serabe.com]
- * * {Patrick Mahoney}[http://polycrystal.org]
- * * {Yoko Harada}[http://yokolet.blogspot.com]
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * 'Software'), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
package nokogiri;
import static nokogiri.internals.NokogiriHelpers.getLocalNameForNamespace;
@@ -49,6 +17,7 @@
import org.jruby.RubyString;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
+import org.jruby.runtime.Block;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
@@ -58,146 +27,137 @@
/**
* Class for Nokogiri::XML::DocumentFragment
- *
+ *
* @author sergio
* @author Yoko Harada
*/
-@JRubyClass(name="Nokogiri::XML::DocumentFragment", parent="Nokogiri::XML::Node")
-public class XmlDocumentFragment extends XmlNode {
- private XmlElement fragmentContext = null;
-
- public XmlDocumentFragment(Ruby ruby) {
- this(ruby, getNokogiriClass(ruby, "Nokogiri::XML::DocumentFragment"));
+@JRubyClass(name = "Nokogiri::XML::DocumentFragment", parent = "Nokogiri::XML::Node")
+public class XmlDocumentFragment extends XmlNode
+{
+ private static final long serialVersionUID = 1L;
+
+ public
+ XmlDocumentFragment(Ruby ruby)
+ {
+ this(ruby, getNokogiriClass(ruby, "Nokogiri::XML::DocumentFragment"));
+ }
+
+ public
+ XmlDocumentFragment(Ruby ruby, RubyClass klazz)
+ {
+ super(ruby, klazz);
+ }
+
+ @JRubyMethod(name = "new", meta = true, required = 1, optional = 3)
+ public static IRubyObject
+ rbNew(ThreadContext context, IRubyObject cls, IRubyObject[] args, Block block)
+ {
+ if (args.length < 1) {
+ throw context.runtime.newArgumentError(args.length, 1);
}
- public XmlDocumentFragment(Ruby ruby, RubyClass klazz) {
- super(ruby, klazz);
- }
-
- @JRubyMethod(name="new", meta = true, required=1, optional=2)
- public static IRubyObject rbNew(ThreadContext context, IRubyObject cls, IRubyObject[] args) {
-
- if(args.length < 1) {
- throw context.getRuntime().newArgumentError(args.length, 1);
- }
-
- if(!(args[0] instanceof XmlDocument)){
- throw context.getRuntime().newArgumentError("first parameter must be a Nokogiri::XML::Document instance");
- }
-
- XmlDocument doc = (XmlDocument) args[0];
-
- // make wellformed fragment, ignore invalid namespace, or add appropriate namespace to parse
- if (args.length > 1 && args[1] instanceof RubyString) {
- if (XmlDocumentFragment.isTag((RubyString)args[1])) {
- args[1] = RubyString.newString(context.getRuntime(), addNamespaceDeclIfNeeded(doc, rubyStringToString(args[1])));
- }
- }
-
- XmlDocumentFragment fragment = (XmlDocumentFragment) NokogiriService.XML_DOCUMENT_FRAGMENT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass)cls);
- fragment.setDocument(context, doc);
- fragment.setNode(context, doc.getDocument().createDocumentFragment());
-
- //TODO: Get namespace definitions from doc.
- if (args.length == 3 && args[2] != null && args[2] instanceof XmlElement) {
- fragment.fragmentContext = (XmlElement)args[2];
- }
- Helpers.invoke(context, fragment, "initialize", args);
- return fragment;
+ if (!(args[0] instanceof XmlDocument)) {
+ throw context.runtime.newArgumentError("first parameter must be a Nokogiri::XML::Document instance");
}
- private static final ByteList TAG_BEG = ByteList.create("<");
- private static final ByteList TAG_END = ByteList.create(">");
-
- private static boolean isTag(final RubyString str) {
- return str.getByteList().startsWith(TAG_BEG) && str.getByteList().endsWith(TAG_END);
- }
+ XmlDocument doc = (XmlDocument) args[0];
- private static boolean isNamespaceDefined(String qName, NamedNodeMap nodeMap) {
- if (isNamespace(qName.intern())) return true;
- for (int i=0; i < nodeMap.getLength(); i++) {
- Attr attr = (Attr)nodeMap.item(i);
- if (isNamespace(attr.getNodeName())) {
- String localPart = getLocalNameForNamespace(attr.getNodeName());
- if (getPrefix(qName).equals(localPart)) {
- return true;
- }
- }
- }
- return false;
+ // make wellformed fragment, ignore invalid namespace, or add appropriate namespace to parse
+ if (args.length > 1 && args[1] instanceof RubyString) {
+ final RubyString arg1 = (RubyString) args[1];
+ if (XmlDocumentFragment.isTag(arg1)) {
+ args[1] = RubyString.newString(context.runtime, addNamespaceDeclIfNeeded(doc, rubyStringToString(arg1)));
+ }
}
- private static final Pattern QNAME_RE = Pattern.compile("[^\\s]+:[^=\\s]+");
- private static final Pattern START_TAG_RE = Pattern.compile("<[^>]+>");
-
- private static String addNamespaceDeclIfNeeded(XmlDocument doc, String tags) {
- if (doc.getDocument() == null) return tags;
- if (doc.getDocument().getDocumentElement() == null) return tags;
- Matcher matcher = START_TAG_RE.matcher(tags);
- Map rewriteTable = null;
- while (matcher.find()) {
- String start_tag = matcher.group();
- Matcher matcher2 = QNAME_RE.matcher(start_tag);
- while (matcher2.find()) {
- String qName = matcher2.group();
- NamedNodeMap nodeMap = doc.getDocument().getDocumentElement().getAttributes();
- if (isNamespaceDefined(qName, nodeMap)) {
- CharSequence namespaceDecl = getNamespaceDecl(getPrefix(qName), nodeMap);
- if (namespaceDecl != null) {
- if (rewriteTable == null) rewriteTable = new HashMap(8, 1);
- StringBuilder str = new StringBuilder(qName.length() + namespaceDecl.length() + 3);
- String key = str.append('<').append(qName).append('>').toString();
- str.setCharAt(key.length() - 1, ' '); // (last) '>' -> ' '
- rewriteTable.put(key, str.append(namespaceDecl).append('>'));
- }
- }
- }
+ XmlDocumentFragment fragment = (XmlDocumentFragment) NokogiriService.XML_DOCUMENT_FRAGMENT_ALLOCATOR.allocate(
+ context.runtime, (RubyClass)cls);
+ fragment.setDocument(context, doc);
+ fragment.setNode(context.runtime, doc.getDocument().createDocumentFragment());
+
+ Helpers.invoke(context, fragment, "initialize", args, block);
+ return fragment;
+ }
+
+ private static final ByteList TAG_BEG = ByteList.create("<");
+ private static final ByteList TAG_END = ByteList.create(">");
+
+ private static boolean
+ isTag(final RubyString str)
+ {
+ return str.getByteList().startsWith(TAG_BEG) && str.getByteList().endsWith(TAG_END);
+ }
+
+ private static boolean
+ isNamespaceDefined(String qName, NamedNodeMap nodeMap)
+ {
+ if (isNamespace(qName.intern())) { return true; }
+ for (int i = 0; i < nodeMap.getLength(); i++) {
+ Attr attr = (Attr)nodeMap.item(i);
+ if (isNamespace(attr.getNodeName())) {
+ String localPart = getLocalNameForNamespace(attr.getNodeName(), null);
+ if (getPrefix(qName).equals(localPart)) {
+ return true;
}
- if (rewriteTable != null) {
- for (Map.Entry e : rewriteTable.entrySet()) {
- tags = tags.replace(e.getKey(), e.getValue());
- }
- }
-
- return tags;
+ }
}
-
- private static CharSequence getNamespaceDecl(final String prefix, NamedNodeMap nodeMap) {
- for (int i=0; i < nodeMap.getLength(); i++) {
- Attr attr = (Attr) nodeMap.item(i);
- if (prefix.equals(attr.getLocalName())) {
- return new StringBuilder().
- append(attr.getName()).append('=').append('"').append(attr.getValue()).append('"');
- }
+ return false;
+ }
+
+ private static final Pattern QNAME_RE = Pattern.compile("[^\\s]+:[^=\\s]+");
+ private static final Pattern START_TAG_RE = Pattern.compile("<[^>]+>");
+
+ private static String
+ addNamespaceDeclIfNeeded(XmlDocument doc, String tags)
+ {
+ if (doc.getDocument() == null) { return tags; }
+ if (doc.getDocument().getDocumentElement() == null) { return tags; }
+ Matcher matcher = START_TAG_RE.matcher(tags);
+ Map rewriteTable = null;
+ while (matcher.find()) {
+ String start_tag = matcher.group();
+ Matcher matcher2 = QNAME_RE.matcher(start_tag);
+ while (matcher2.find()) {
+ String qName = matcher2.group();
+ NamedNodeMap nodeMap = doc.getDocument().getDocumentElement().getAttributes();
+ if (isNamespaceDefined(qName, nodeMap)) {
+ CharSequence namespaceDecl = getNamespaceDecl(getPrefix(qName), nodeMap);
+ if (namespaceDecl != null) {
+ if (rewriteTable == null) { rewriteTable = new HashMap(8, 1); }
+ StringBuilder str = new StringBuilder(qName.length() + namespaceDecl.length() + 3);
+ String key = str.append('<').append(qName).append('>').toString();
+ str.setCharAt(key.length() - 1, ' '); // (last) '>' -> ' '
+ rewriteTable.put(key, str.append(namespaceDecl).append('>'));
+ }
}
- return null;
+ }
}
-
- public XmlElement getFragmentContext() {
- return fragmentContext;
- }
-
- //@Override
- public void add_child(ThreadContext context, XmlNode child) {
- // Some magic for DocumentFragment
-
- Ruby ruby = context.getRuntime();
- XmlNodeSet children = (XmlNodeSet) child.children(context);
-
- long length = children.length();
-
- RubyArray childrenArray = children.convertToArray();
-
- if(length != 0) {
- for(int i = 0; i < length; i++) {
- XmlNode item = (XmlNode) ((XmlNode) childrenArray.aref(ruby.newFixnum(i))).dup_implementation(context, true);
- add_child(context, item);
- }
- }
+ if (rewriteTable != null) {
+ for (Map.Entry e : rewriteTable.entrySet()) {
+ tags = tags.replace(e.getKey(), e.getValue());
+ }
}
- @Override
- public void relink_namespace(ThreadContext context) {
- ((XmlNodeSet) children(context)).relink_namespace(context);
+ return tags;
+ }
+
+ private static CharSequence
+ getNamespaceDecl(final String prefix, NamedNodeMap nodeMap)
+ {
+ for (int i = 0; i < nodeMap.getLength(); i++) {
+ Attr attr = (Attr) nodeMap.item(i);
+ if (prefix.equals(attr.getLocalName())) {
+ return new StringBuilder().
+ append(attr.getName()).append('=').append('"').append(attr.getValue()).append('"');
+ }
}
+ return null;
+ }
+
+ @Override
+ public void
+ relink_namespace(ThreadContext context)
+ {
+ relink_namespace(context, getChildren());
+ }
}
diff --git a/ext/java/nokogiri/XmlDtd.java b/ext/java/nokogiri/XmlDtd.java
index 6083454bd5..492fed62c4 100644
--- a/ext/java/nokogiri/XmlDtd.java
+++ b/ext/java/nokogiri/XmlDtd.java
@@ -1,35 +1,3 @@
-/**
- * (The MIT License)
- *
- * Copyright (c) 2008 - 2011:
- *
- * * {Aaron Patterson}[http://tenderlovemaking.com]
- * * {Mike Dalessio}[http://mike.daless.io]
- * * {Charles Nutter}[http://blog.headius.com]
- * * {Sergio Arbeo}[http://www.serabe.com]
- * * {Patrick Mahoney}[http://polycrystal.org]
- * * {Yoko Harada}[http://yokolet.blogspot.com]
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * 'Software'), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
package nokogiri;
import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
@@ -61,424 +29,488 @@
/**
* Class for Nokogiri::XML::DTD
- *
+ *
* @author sergio
* @author Patrick Mahoney
* @author Yoko Harada
*/
+@JRubyClass(name = "Nokogiri::XML::DTD", parent = "Nokogiri::XML::Node")
+public class XmlDtd extends XmlNode
+{
+ private static final long serialVersionUID = 1L;
-@JRubyClass(name="Nokogiri::XML::DTD", parent="Nokogiri::XML::Node")
-public class XmlDtd extends XmlNode {
- /** cache of children, Nokogiri::XML::NodeSet */
- protected IRubyObject children = null;
-
- /** cache of name => XmlAttributeDecl */
- protected RubyHash attributes = null;
-
- /** cache of name => XmlElementDecl */
- protected RubyHash elements = null;
-
- /** cache of name => XmlEntityDecl */
- protected RubyHash entities = null;
-
- /** cache of name => Nokogiri::XML::Notation */
- protected RubyHash notations = null;
- protected RubyClass notationClass;
-
- /** temporary store of content models before they are added to
- * their XmlElementDecl. */
- protected RubyHash contentModels;
-
- /** node name */
- protected IRubyObject name;
-
- /** public ID (or external ID) */
- protected IRubyObject pubId;
-
- /** system ID */
- protected IRubyObject sysId;
-
- public XmlDtd(Ruby ruby, RubyClass rubyClass) {
- super(ruby, rubyClass);
- }
-
- public void setNode(Ruby runtime, Node dtd) {
- this.node = dtd;
- notationClass = (RubyClass) runtime.getClassFromPath("Nokogiri::XML::Notation");
-
- name = pubId = sysId = runtime.getNil();
- if (dtd == null) return;
-
- // This is the dtd declaration stored in the document; it
- // contains the DTD name (root element) and public and system
- // ids. The actual declarations are in the NekoDTD 'dtd'
- // variable. I don't know of a way to consolidate the two.
-
- DocumentType otherDtd = dtd.getOwnerDocument().getDoctype();
- if (otherDtd != null) {
- name = stringOrNil(runtime, otherDtd.getNodeName());
- pubId = nonEmptyStringOrNil(runtime, otherDtd.getPublicId());
- sysId = nonEmptyStringOrNil(runtime, otherDtd.getSystemId());
- }
- }
-
- public XmlDtd(Ruby ruby, RubyClass rubyClass, Node dtd) {
- super(ruby, rubyClass, dtd);
- setNode(ruby, dtd);
- }
-
- public static XmlDtd newEmpty(Ruby runtime,
- Document doc,
- IRubyObject name,
- IRubyObject external_id,
- IRubyObject system_id) {
-
- DocumentType placeholder;
- if (doc.getDoctype() == null) {
- String javaName = NokogiriHelpers.rubyStringToString(name);
- String javaExternalId = NokogiriHelpers.rubyStringToString(external_id);
- String javaSystemId = NokogiriHelpers.rubyStringToString(system_id);
- placeholder = doc.getImplementation().createDocumentType(javaName, javaExternalId, javaSystemId);
- doc.appendChild(placeholder);
- } else {
- placeholder = doc.getDoctype();
- }
- // FIXME: what if the document had a doc type, why are we here ?
- XmlDtd dtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::DTD"));
- dtd.setNode(runtime, placeholder);
- dtd.name = name;
- dtd.pubId = external_id;
- dtd.sysId = system_id;
- return dtd;
- }
-
+ /** cache of children, Nokogiri::XML::NodeSet */
+ protected IRubyObject children = null;
- /**
- * Create an unparented element that contains DTD declarations
- * parsed from the internal subset attached as user data to
- * doc. The attached dtd must be the tree from
- * NekoDTD. The owner document of the returned tree will be
- * doc.
- *
- * NekoDTD parser returns a new document node containing elements
- * representing the dtd declarations. The plan is to get the root
- * element and adopt it into the correct document, stipping the
- * Document provided by NekoDTD.
- *
- */
- public static XmlDtd newFromInternalSubset(Ruby runtime, Document doc) {
- Object dtdTree_ = doc.getUserData(XmlDocument.DTD_RAW_DOCUMENT);
- if (dtdTree_ == null) {
- XmlDtd xmlDtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::DTD"));
- xmlDtd.setNode(runtime, null);
- return xmlDtd;
- }
-
- Node dtdTree = (Node) dtdTree_;
- Node dtd = getInternalSubset(dtdTree);
- if (dtd == null) {
- XmlDtd xmlDtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::DTD"));
- xmlDtd.setNode(runtime, null);
- return xmlDtd;
- } else {
- // Import the node into doc so it has the correct owner document.
- dtd = doc.importNode(dtd, true);
- XmlDtd xmlDtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::DTD"));
- xmlDtd.setNode(runtime, dtd);
- return xmlDtd;
- }
- }
-
- public static IRubyObject newFromExternalSubset(Ruby runtime, Document doc) {
- Object dtdTree_ = doc.getUserData(XmlDocument.DTD_RAW_DOCUMENT);
- if (dtdTree_ == null) {
- return runtime.getNil();
- }
-
- Node dtdTree = (Node) dtdTree_;
- Node dtd = getExternalSubset(dtdTree);
- if (dtd == null) {
- return runtime.getNil();
- } else if (!dtd.hasChildNodes()) {
- return runtime.getNil();
- } else {
- // Import the node into doc so it has the correct owner document.
- dtd = doc.importNode(dtd, true);
- XmlDtd xmlDtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::DTD"));
- xmlDtd.setNode(runtime, dtd);
- return xmlDtd;
- }
- }
+ /** cache of name => XmlAttributeDecl */
+ protected RubyHash attributes = null;
- /*
- * dtd is the document node of a NekoDTD tree.
- * NekoDTD tree looks like this:
- *
- *