Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: ensure parsed fragments are always of the right type
Introduce ClassResolver which will do the class lookup correctly, and use it for Builder and for fragment parsing. Closes #1158
- Loading branch information
1 parent
86504a1
commit 38c2f16
Showing
8 changed files
with
108 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# coding: utf-8 | ||
# frozen_string_literal: true | ||
|
||
require "set" | ||
|
||
module Nokogiri | ||
# | ||
# Some classes in Nokogiri are namespaced as a group, for example | ||
# Document, DocumentFragment, and Builder. | ||
# | ||
# It's sometimes necessary to look up the related class, e.g.: | ||
# | ||
# XML::Builder → XML::Document | ||
# HTML4::Builder → HTML4::Document | ||
# HTML5::Document → HTML5::DocumentFragment | ||
# | ||
# This module is included into those key classes who need to do this. | ||
# | ||
module ClassResolver | ||
# #related_class restricts matching namespaces to those matching this set. | ||
VALID_NAMESPACES = Set.new(["HTML", "HTML4", "HTML5", "XML"]) | ||
|
||
# :call-seq: | ||
# related_class(class_name) → Class | ||
# | ||
# Find a class constant within the | ||
# | ||
# Some examples: | ||
# | ||
# Nokogiri::XML::Document.new.related_class("DocumentFragment") | ||
# # => Nokogiri::XML::DocumentFragment | ||
# Nokogiri::HTML4::Document.new.related_class("DocumentFragment") | ||
# # => Nokogiri::HTML4::DocumentFragment | ||
# | ||
# Note this will also work for subclasses that follow the same convention, e.g.: | ||
# | ||
# Loofah::HTML::Document.new.related_class("DocumentFragment") | ||
# # => Loofah::HTML::DocumentFragment | ||
# | ||
# And even if it's a subclass, this will iterate through the superclasses: | ||
# | ||
# class ThisIsATopLevelClass < Nokogiri::HTML4::Builder ; end | ||
# ThisIsATopLevelClass.new.related_class("Document") | ||
# # => Nokogiri::HTML4::Document | ||
# | ||
def related_class(class_name) | ||
klass = nil | ||
inspecting = self.class | ||
|
||
while inspecting | ||
namespace_path = inspecting.name.split("::")[0..-2] | ||
inspecting = inspecting.superclass | ||
|
||
next unless VALID_NAMESPACES.include?(namespace_path.last) | ||
|
||
related_class_name = (namespace_path << class_name).join("::") | ||
klass = begin | ||
Object.const_get(related_class_name) | ||
rescue NameError | ||
nil | ||
end | ||
break if klass | ||
end | ||
klass | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters