moxml 0.1.21 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/opal.yml +37 -0
- data/.gitignore +1 -0
- data/.rspec-opal +5 -0
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +680 -110
- data/Gemfile +6 -0
- data/Rakefile +70 -0
- data/lib/compat/opal/rexml/namespace.rb +59 -0
- data/lib/compat/opal/rexml/parsers/baseparser.rb +1016 -0
- data/lib/compat/opal/rexml/source.rb +214 -0
- data/lib/compat/opal/rexml/text.rb +426 -0
- data/lib/compat/opal/rexml/xmltokens.rb +45 -0
- data/lib/compat/opal/rexml_compat.rb +77 -0
- data/lib/moxml/adapter/customized_oga/xml_declaration.rb +8 -1
- data/lib/moxml/adapter/customized_rexml/formatter.rb +11 -10
- data/lib/moxml/adapter/headed_ox.rb +2 -6
- data/lib/moxml/adapter/libxml/entity_ref_registry.rb +4 -2
- data/lib/moxml/adapter/libxml/entity_restorer.rb +3 -1
- data/lib/moxml/adapter/libxml.rb +22 -24
- data/lib/moxml/adapter/nokogiri.rb +24 -33
- data/lib/moxml/adapter/oga.rb +47 -84
- data/lib/moxml/adapter/ox.rb +43 -41
- data/lib/moxml/adapter/rexml.rb +29 -33
- data/lib/moxml/adapter.rb +38 -8
- data/lib/moxml/config.rb +16 -3
- data/lib/moxml/document.rb +2 -8
- data/lib/moxml/entity_registry.rb +40 -31
- data/lib/moxml/entity_registry_opal_data.rb +2138 -0
- data/lib/moxml/node.rb +27 -26
- data/lib/moxml/sax/namespace_splitter.rb +54 -0
- data/lib/moxml/version.rb +1 -1
- data/lib/moxml/xml_utils.rb +10 -1
- data/lib/moxml.rb +7 -0
- data/spec/consistency/adapter_parity_spec.rb +1 -1
- data/spec/integration/all_adapters_spec.rb +2 -1
- data/spec/integration/shared_examples/line_ending_behavior.rb +56 -0
- data/spec/integration/w3c_namespace_spec.rb +1 -1
- data/spec/moxml/adapter/libxml_internals_spec.rb +4 -2
- data/spec/moxml/adapter/ox_spec.rb +8 -0
- data/spec/moxml/adapter/platform_spec.rb +70 -0
- data/spec/moxml/adapter/shared_examples/adapter_contract.rb +0 -6
- data/spec/moxml/config_spec.rb +33 -0
- data/spec/moxml/entity_registry_spec.rb +10 -0
- data/spec/moxml/native_attachment/opal_spec.rb +39 -2
- data/spec/moxml/node_type_map_spec.rb +43 -0
- data/spec/moxml/opal_rexml_adapter_spec.rb +14 -0
- data/spec/moxml/opal_smoke_spec.rb +61 -0
- data/spec/moxml/sax/namespace_splitter_spec.rb +67 -0
- data/spec/moxml/text_spec.rb +1 -1
- data/spec/spec_helper.rb +32 -13
- data/spec/support/opal.rb +16 -0
- metadata +19 -2
data/Gemfile
CHANGED
data/Rakefile
CHANGED
|
@@ -5,11 +5,43 @@ require "rspec/core/rake_task"
|
|
|
5
5
|
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
|
7
7
|
|
|
8
|
+
begin
|
|
9
|
+
require "opal/rspec/rake_task"
|
|
10
|
+
|
|
11
|
+
# REXML is a bundled gem since Ruby 3.4; its source must be on Opal's
|
|
12
|
+
# global load path so the compiler can follow `require "rexml/document"`.
|
|
13
|
+
# Opal-compatible overrides go first so they shadow the gem originals.
|
|
14
|
+
if defined?(Opal)
|
|
15
|
+
Opal.append_path File.expand_path("lib/compat/opal", __dir__)
|
|
16
|
+
rexml_lib = $LOAD_PATH.find do |p|
|
|
17
|
+
File.exist?(File.join(p, "rexml", "document.rb"))
|
|
18
|
+
end
|
|
19
|
+
Opal.append_path rexml_lib if rexml_lib
|
|
20
|
+
end
|
|
21
|
+
rescue LoadError
|
|
22
|
+
# Opal not available or incompatible with current Ruby version
|
|
23
|
+
end
|
|
24
|
+
|
|
8
25
|
require "rubocop/rake_task"
|
|
9
26
|
|
|
10
27
|
RuboCop::RakeTask.new
|
|
11
28
|
|
|
12
29
|
namespace :spec do
|
|
30
|
+
if defined?(Opal::RSpec::RakeTask)
|
|
31
|
+
desc "Run Opal (JavaScript) tests"
|
|
32
|
+
Opal::RSpec::RakeTask.new(:opal) do |server, runner|
|
|
33
|
+
server.append_path "lib"
|
|
34
|
+
server.append_path "spec"
|
|
35
|
+
|
|
36
|
+
runner.default_path = "spec"
|
|
37
|
+
runner.requires = %w[rexml_compat rexml/document rexml/xpath
|
|
38
|
+
moxml/adapter/rexml spec_helper support/opal]
|
|
39
|
+
runner.files = Dir.glob("spec/moxml/*opal*_spec.rb") +
|
|
40
|
+
Dir.glob("spec/moxml/native_attachment/opal_spec.rb") +
|
|
41
|
+
Dir.glob("spec/moxml/adapter/shared_examples/*.rb")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
13
45
|
desc "Validate XML fixtures are well-formed (requires xmllint)"
|
|
14
46
|
task :validate_fixtures do
|
|
15
47
|
fixtures = Dir.glob("spec/fixtures/**/*.xml")
|
|
@@ -106,4 +138,42 @@ namespace :benchmark do
|
|
|
106
138
|
end
|
|
107
139
|
end
|
|
108
140
|
|
|
141
|
+
namespace :opal do
|
|
142
|
+
desc "Regenerate entity data for Opal from w3c_entities.json"
|
|
143
|
+
task :generate_entity_data do
|
|
144
|
+
require "json"
|
|
145
|
+
|
|
146
|
+
source = File.join(__dir__, "data", "w3c_entities.json")
|
|
147
|
+
target = File.join(__dir__, "lib", "moxml", "entity_registry_opal_data.rb")
|
|
148
|
+
|
|
149
|
+
data = JSON.parse(File.read(source))
|
|
150
|
+
chars = data["characters"]
|
|
151
|
+
|
|
152
|
+
lines = []
|
|
153
|
+
lines << "# frozen_string_literal: true"
|
|
154
|
+
lines << "#"
|
|
155
|
+
lines << "# Auto-generated entity data for Opal runtime."
|
|
156
|
+
lines << "# Source: data/w3c_entities.json (#{chars.size} entities)"
|
|
157
|
+
lines << "# Regenerate with: rake opal:generate_entity_data"
|
|
158
|
+
lines << ""
|
|
159
|
+
lines << "module Moxml"
|
|
160
|
+
lines << " class EntityRegistry"
|
|
161
|
+
lines << " OPAL_ENTITY_DATA = {"
|
|
162
|
+
chars.each do |name, char|
|
|
163
|
+
codepoint = if char.start_with?("\\u")
|
|
164
|
+
char.unicode_normalize(:nfc)[2..].to_i(16)
|
|
165
|
+
else
|
|
166
|
+
char.ord
|
|
167
|
+
end
|
|
168
|
+
lines << " #{name.inspect} => #{codepoint},"
|
|
169
|
+
end
|
|
170
|
+
lines << " }.freeze"
|
|
171
|
+
lines << " end"
|
|
172
|
+
lines << "end"
|
|
173
|
+
|
|
174
|
+
File.write(target, "#{lines.join("\n")}\n")
|
|
175
|
+
puts "Generated #{target} (#{chars.size} entities, #{lines.size} lines)"
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
109
179
|
task default: %i[spec rubocop]
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rexml/xmltokens"
|
|
4
|
+
|
|
5
|
+
module REXML
|
|
6
|
+
module Namespace
|
|
7
|
+
attr_reader :name, :expanded_name
|
|
8
|
+
attr_accessor :prefix
|
|
9
|
+
|
|
10
|
+
include XMLTokens
|
|
11
|
+
|
|
12
|
+
NAME_WITHOUT_NAMESPACE = /^#{NCNAME_STR}$/
|
|
13
|
+
NAMESPLIT = /^(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})/u
|
|
14
|
+
|
|
15
|
+
def name=(name)
|
|
16
|
+
@expanded_name = name
|
|
17
|
+
if name.match?(NAME_WITHOUT_NAMESPACE)
|
|
18
|
+
@prefix = ""
|
|
19
|
+
@namespace = ""
|
|
20
|
+
@name = name
|
|
21
|
+
elsif name =~ NAMESPLIT
|
|
22
|
+
if $1
|
|
23
|
+
@prefix = $1
|
|
24
|
+
else
|
|
25
|
+
@prefix = ""
|
|
26
|
+
@namespace = ""
|
|
27
|
+
end
|
|
28
|
+
@name = $2
|
|
29
|
+
elsif name == ""
|
|
30
|
+
@prefix = nil
|
|
31
|
+
@namespace = nil
|
|
32
|
+
@name = nil
|
|
33
|
+
else
|
|
34
|
+
message = "name must be \#{PREFIX}:\#{LOCAL_NAME} or \#{LOCAL_NAME}: "
|
|
35
|
+
message += "<#{name.inspect}>"
|
|
36
|
+
raise ArgumentError, message
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def has_name?(other, ns = nil)
|
|
41
|
+
if ns
|
|
42
|
+
namespace == ns and name == other
|
|
43
|
+
elsif other.include? ":"
|
|
44
|
+
fully_expanded_name == other
|
|
45
|
+
else
|
|
46
|
+
name == other
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
alias :local_name :name
|
|
51
|
+
|
|
52
|
+
def fully_expanded_name
|
|
53
|
+
ns = prefix
|
|
54
|
+
return "#{ns}:#@name" if ns.size.positive?
|
|
55
|
+
|
|
56
|
+
@name
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|