Skip to content

Commit

Permalink
Merge pull request #2230 from sparklemotion/2228-attribute-with-ns-in…
Browse files Browse the repository at this point in the history
…sertion

fix: ensure namespaced attributes are reparented properly
  • Loading branch information
flavorjones committed May 11, 2021
2 parents 8387bcf + cd6941f commit 051b193
Show file tree
Hide file tree
Showing 22 changed files with 871 additions and 829 deletions.
26 changes: 21 additions & 5 deletions CHANGELOG.md
Expand Up @@ -6,20 +6,36 @@ Nokogiri follows [Semantic Versioning](https://semver.org/), please see the [REA

## next / unreleased

### Dependencies
### Added

__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).

* [MRI] Upgrade mini_portile2 dependency from `~> 2.5.0` to `~> 2.5.1`.
Please also note that the `Nokogiri::HTML` parse methods still use libxml2's HTML4 parser in the v1.12 release series. Future releases of Nokogiri may change this behavior, but we'll proceed cautiously to avoid breaking existing applications.

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. 🙌


### Changed

* Introduce `Nokogiri::XML::ParseOptions::DEFAULT_XSLT` which adds the libxslt-preferred options of `NOENT | DTDLOAD | DTDATTR | NOCDATA` to `ParseOptions::DEFAULT_XML`.
* `Nokogiri.XSLT` parses the stylesheet 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)]
* 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)]


### Improved

* [MRI] Speed up (slightly) the compile time of packaged libraries `libiconv`, `libxml2`, and `libxslt` by using autoconf's `--disable-dependency-tracking` option.
* [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.)


### Dependencies

* [CRuby] Upgrade mini_portile2 dependency from `~> 2.5.0` to `~> 2.5.1`. ("ruby" platform gem only.)


## 1.11.3 / 2021-04-07
Expand Down
22 changes: 11 additions & 11 deletions ext/java/nokogiri/XmlDocument.java
Expand Up @@ -657,17 +657,17 @@ private static class DocumentBuilderFactoryHolder
}
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; }
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);
Expand Down
10 changes: 5 additions & 5 deletions ext/java/nokogiri/XmlElementContent.java
Expand Up @@ -142,11 +142,11 @@ public IRubyObject value(Ruby runtime)
right = runtime.getNil();

switch (type) {
case SEQ:
case OR:
applyGroup(runtime, klass, doc, iter);
default:
// noop
case SEQ:
case OR:
applyGroup(runtime, klass, doc, iter);
default:
// noop
}
}

Expand Down
132 changes: 66 additions & 66 deletions ext/java/nokogiri/XmlNode.java
Expand Up @@ -1516,56 +1516,56 @@ public class XmlNode extends RubyObject
{
String type;
switch (node.getNodeType()) {
case Node.ELEMENT_NODE:
if (this instanceof XmlElementDecl) {
type = "ELEMENT_DECL";
} else if (this instanceof XmlAttributeDecl) {
type = "ATTRIBUTE_DECL";
} else if (this instanceof XmlEntityDecl) {
type = "ENTITY_DECL";
} else {
type = "ELEMENT_NODE";
}
break;
case Node.ATTRIBUTE_NODE:
type = "ATTRIBUTE_NODE";
break;
case Node.TEXT_NODE:
type = "TEXT_NODE";
break;
case Node.CDATA_SECTION_NODE:
type = "CDATA_SECTION_NODE";
break;
case Node.ENTITY_REFERENCE_NODE:
type = "ENTITY_REF_NODE";
break;
case Node.ENTITY_NODE:
type = "ENTITY_NODE";
break;
case Node.PROCESSING_INSTRUCTION_NODE:
type = "PI_NODE";
break;
case Node.COMMENT_NODE:
type = "COMMENT_NODE";
break;
case Node.DOCUMENT_NODE:
if (this instanceof HtmlDocument) {
type = "HTML_DOCUMENT_NODE";
} else {
type = "DOCUMENT_NODE";
}
break;
case Node.DOCUMENT_TYPE_NODE:
type = "DOCUMENT_TYPE_NODE";
break;
case Node.DOCUMENT_FRAGMENT_NODE:
type = "DOCUMENT_FRAG_NODE";
break;
case Node.NOTATION_NODE:
type = "NOTATION_NODE";
break;
default:
return context.runtime.newFixnum(0);
case Node.ELEMENT_NODE:
if (this instanceof XmlElementDecl) {
type = "ELEMENT_DECL";
} else if (this instanceof XmlAttributeDecl) {
type = "ATTRIBUTE_DECL";
} else if (this instanceof XmlEntityDecl) {
type = "ENTITY_DECL";
} else {
type = "ELEMENT_NODE";
}
break;
case Node.ATTRIBUTE_NODE:
type = "ATTRIBUTE_NODE";
break;
case Node.TEXT_NODE:
type = "TEXT_NODE";
break;
case Node.CDATA_SECTION_NODE:
type = "CDATA_SECTION_NODE";
break;
case Node.ENTITY_REFERENCE_NODE:
type = "ENTITY_REF_NODE";
break;
case Node.ENTITY_NODE:
type = "ENTITY_NODE";
break;
case Node.PROCESSING_INSTRUCTION_NODE:
type = "PI_NODE";
break;
case Node.COMMENT_NODE:
type = "COMMENT_NODE";
break;
case Node.DOCUMENT_NODE:
if (this instanceof HtmlDocument) {
type = "HTML_DOCUMENT_NODE";
} else {
type = "DOCUMENT_NODE";
}
break;
case Node.DOCUMENT_TYPE_NODE:
type = "DOCUMENT_TYPE_NODE";
break;
case Node.DOCUMENT_FRAGMENT_NODE:
type = "DOCUMENT_FRAG_NODE";
break;
case Node.NOTATION_NODE:
type = "NOTATION_NODE";
break;
default:
return context.runtime.newFixnum(0);
}

return getNokogiriClass(context.runtime, "Nokogiri::XML::Node").getConstant(type);
Expand Down Expand Up @@ -1676,23 +1676,23 @@ protected enum AdoptScheme {
Node parent = thisNode.getParentNode();

switch (scheme) {
case CHILD:
Node[] children = adoptAsChild(thisNode, otherNode);
if (children.length == 1 && otherNode == children[0]) {
case CHILD:
Node[] children = adoptAsChild(thisNode, otherNode);
if (children.length == 1 && otherNode == children[0]) {
break;
} else {
nodeOrTags = nodeArrayToRubyArray(context.runtime, children);
}
break;
case PREV_SIBLING:
adoptAsPrevSibling(context, parent, thisNode, otherNode);
break;
case NEXT_SIBLING:
adoptAsNextSibling(context, parent, thisNode, otherNode);
break;
case REPLACEMENT:
adoptAsReplacement(context, parent, thisNode, otherNode);
break;
} else {
nodeOrTags = nodeArrayToRubyArray(context.runtime, children);
}
break;
case PREV_SIBLING:
adoptAsPrevSibling(context, parent, thisNode, otherNode);
break;
case NEXT_SIBLING:
adoptAsNextSibling(context, parent, thisNode, otherNode);
break;
case REPLACEMENT:
adoptAsReplacement(context, parent, thisNode, otherNode);
break;
}
} catch (Exception e) {
throw context.runtime.newRuntimeError(e.toString());
Expand Down
18 changes: 9 additions & 9 deletions ext/java/nokogiri/XmlXpathContext.java
Expand Up @@ -203,15 +203,15 @@ public class XmlXpathContext extends RubyObject
}

switch (xobj.getType()) {
case XObject.CLASS_BOOLEAN :
return context.runtime.newBoolean(xobj.bool());
case XObject.CLASS_NUMBER :
return context.runtime.newFloat(xobj.num());
case XObject.CLASS_NODESET :
IRubyObject[] nodes = nodeListToRubyArray(context.runtime, xobj.nodelist());
return XmlNodeSet.newNodeSet(context.runtime, nodes, this.context);
default :
return context.runtime.newString(xobj.str());
case XObject.CLASS_BOOLEAN :
return context.runtime.newBoolean(xobj.bool());
case XObject.CLASS_NUMBER :
return context.runtime.newFloat(xobj.num());
case XObject.CLASS_NODESET :
IRubyObject[] nodes = nodeListToRubyArray(context.runtime, xobj.nodelist());
return XmlNodeSet.newNodeSet(context.runtime, nodes, this.context);
default :
return context.runtime.newString(xobj.str());
}
}

Expand Down
12 changes: 6 additions & 6 deletions ext/java/nokogiri/XsltStylesheet.java
Expand Up @@ -213,12 +213,12 @@ public class XsltStylesheet extends RubyObject
}

switch (elistener.getErrorType()) {
case ERROR:
case FATAL:
throw runtime.newRuntimeError(elistener.getErrorMessage());
case WARNING:
default:
// no-op
case ERROR:
case FATAL:
throw runtime.newRuntimeError(elistener.getErrorMessage());
case WARNING:
default:
// no-op
}

if (stringResult == null) {
Expand Down
106 changes: 53 additions & 53 deletions ext/java/nokogiri/internals/NokogiriHelpers.java
Expand Up @@ -116,59 +116,59 @@ public class NokogiriHelpers
if (node == null) { return runtime.getNil(); }
// this is slow; need a way to cache nokogiri classes/modules somewhere
switch (node.getNodeType()) {
case Node.ELEMENT_NODE:
XmlElement xmlElement = (XmlElement) NokogiriService.XML_ELEMENT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::Element"));
xmlElement.setNode(runtime, node);
return xmlElement;
case Node.ATTRIBUTE_NODE:
XmlAttr xmlAttr = (XmlAttr) NokogiriService.XML_ATTR_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::Attr"));
xmlAttr.setNode(runtime, node);
return xmlAttr;
case Node.TEXT_NODE:
XmlText xmlText = (XmlText) NokogiriService.XML_TEXT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::Text"));
xmlText.setNode(runtime, node);
return xmlText;
case Node.COMMENT_NODE:
XmlComment xmlComment = (XmlComment) NokogiriService.XML_COMMENT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::Comment"));
xmlComment.setNode(runtime, node);
return xmlComment;
case Node.ENTITY_NODE:
return new XmlNode(runtime, getNokogiriClass(runtime, "Nokogiri::XML::EntityDecl"), node);
case Node.ENTITY_REFERENCE_NODE:
XmlEntityReference xmlEntityRef = (XmlEntityReference) NokogiriService.XML_ENTITY_REFERENCE_ALLOCATOR.allocate(runtime,
getNokogiriClass(runtime, "Nokogiri::XML::EntityReference"));
xmlEntityRef.setNode(runtime, node);
return xmlEntityRef;
case Node.PROCESSING_INSTRUCTION_NODE:
XmlProcessingInstruction xmlProcessingInstruction = (XmlProcessingInstruction)
NokogiriService.XML_PROCESSING_INSTRUCTION_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::ProcessingInstruction"));
xmlProcessingInstruction.setNode(runtime, node);
return xmlProcessingInstruction;
case Node.CDATA_SECTION_NODE:
XmlCdata xmlCdata = (XmlCdata) NokogiriService.XML_CDATA_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::CDATA"));
xmlCdata.setNode(runtime, node);
return xmlCdata;
case Node.DOCUMENT_NODE:
XmlDocument xmlDocument = (XmlDocument) NokogiriService.XML_DOCUMENT_ALLOCATOR.allocate(runtime,
getNokogiriClass(runtime, "Nokogiri::XML::Document"));
xmlDocument.setDocumentNode(runtime, (Document) node);
return xmlDocument;
case Node.DOCUMENT_TYPE_NODE:
XmlDtd xmlDtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::DTD"));
xmlDtd.setNode(runtime, node);
return xmlDtd;
default:
XmlNode xmlNode = (XmlNode) NokogiriService.XML_NODE_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::Node"));
xmlNode.setNode(runtime, node);
return xmlNode;
case Node.ELEMENT_NODE:
XmlElement xmlElement = (XmlElement) NokogiriService.XML_ELEMENT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::Element"));
xmlElement.setNode(runtime, node);
return xmlElement;
case Node.ATTRIBUTE_NODE:
XmlAttr xmlAttr = (XmlAttr) NokogiriService.XML_ATTR_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::Attr"));
xmlAttr.setNode(runtime, node);
return xmlAttr;
case Node.TEXT_NODE:
XmlText xmlText = (XmlText) NokogiriService.XML_TEXT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::Text"));
xmlText.setNode(runtime, node);
return xmlText;
case Node.COMMENT_NODE:
XmlComment xmlComment = (XmlComment) NokogiriService.XML_COMMENT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::Comment"));
xmlComment.setNode(runtime, node);
return xmlComment;
case Node.ENTITY_NODE:
return new XmlNode(runtime, getNokogiriClass(runtime, "Nokogiri::XML::EntityDecl"), node);
case Node.ENTITY_REFERENCE_NODE:
XmlEntityReference xmlEntityRef = (XmlEntityReference) NokogiriService.XML_ENTITY_REFERENCE_ALLOCATOR.allocate(runtime,
getNokogiriClass(runtime, "Nokogiri::XML::EntityReference"));
xmlEntityRef.setNode(runtime, node);
return xmlEntityRef;
case Node.PROCESSING_INSTRUCTION_NODE:
XmlProcessingInstruction xmlProcessingInstruction = (XmlProcessingInstruction)
NokogiriService.XML_PROCESSING_INSTRUCTION_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::ProcessingInstruction"));
xmlProcessingInstruction.setNode(runtime, node);
return xmlProcessingInstruction;
case Node.CDATA_SECTION_NODE:
XmlCdata xmlCdata = (XmlCdata) NokogiriService.XML_CDATA_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::CDATA"));
xmlCdata.setNode(runtime, node);
return xmlCdata;
case Node.DOCUMENT_NODE:
XmlDocument xmlDocument = (XmlDocument) NokogiriService.XML_DOCUMENT_ALLOCATOR.allocate(runtime,
getNokogiriClass(runtime, "Nokogiri::XML::Document"));
xmlDocument.setDocumentNode(runtime, (Document) node);
return xmlDocument;
case Node.DOCUMENT_TYPE_NODE:
XmlDtd xmlDtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::DTD"));
xmlDtd.setNode(runtime, node);
return xmlDtd;
default:
XmlNode xmlNode = (XmlNode) NokogiriService.XML_NODE_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime,
"Nokogiri::XML::Node"));
xmlNode.setNode(runtime, node);
return xmlNode;
}
}

Expand Down

0 comments on commit 051b193

Please sign in to comment.