Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@xmldom/xmldom

Package Overview
Dependencies
Maintainers
4
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@xmldom/xmldom - npm Package Compare versions

Comparing version 0.7.8 to 0.7.9

9

CHANGELOG.md

@@ -7,2 +7,11 @@ # Changelog

## [0.7.9](https://github.com/xmldom/xmldom/compare/0.7.8...0.7.9)
### Fixed
- Properly check nodes before replacement [`#457`](https://github.com/xmldom/xmldom/pull/457) / [`#455`](https://github.com/xmldom/xmldom/issues/455) / [`#456`](https://github.com/xmldom/xmldom/issues/456)
Thank you, [@edemaine](https://github.com/edemaine), [@pedro-l9](https://github.com/pedro-l9), for your contributions
## [0.7.8](https://github.com/xmldom/xmldom/compare/0.7.7...0.7.8)

@@ -9,0 +18,0 @@

219

lib/dom.js

@@ -471,3 +471,3 @@ var conventions = require("./conventions");

replaceChild:function(newChild, oldChild){//raises
this.insertBefore(newChild,oldChild);
_insertBefore(this, newChild,oldChild, assertPreReplacementValidityInDocument);
if(oldChild){

@@ -596,2 +596,3 @@ this.removeChild(oldChild);

function Document(){
this.ownerDocument = this;
}

@@ -633,2 +634,3 @@

cs.length = i;
delete cs[cs.length];
}

@@ -659,2 +661,5 @@ }

}
child.parentNode = null;
child.previousSibling = null;
child.nextSibling = null;
_onUpdateChild(parentNode.ownerDocument,parentNode);

@@ -737,4 +742,31 @@ return child;

}
/**
* Check if en element node can be inserted before `child`, or at the end if child is falsy,
* according to the presence and position of a doctype node on the same level.
*
* @param {Node} doc The document node
* @param {Node} child the node that would become the nextSibling if the element would be inserted
* @returns {boolean} `true` if an element can be inserted before child
* @private
* https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
*/
function isElementReplacementPossible(doc, child) {
var parentChildNodes = doc.childNodes || [];
function hasElementChildThatIsNotChild(node) {
return isElementNode(node) && node !== child;
}
if (find(parentChildNodes, hasElementChildThatIsNotChild)) {
return false;
}
var docTypeNode = find(parentChildNodes, isDocTypeNode);
return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child));
}
/**
* @private
* Steps 1-5 of the checks before inserting and before replacing a child are the same.
*
* @param {Node} parent the parent node to insert `node` into

@@ -747,7 +779,12 @@ * @param {Node} node the node to insert

* @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
* @see https://dom.spec.whatwg.org/#concept-node-replace
*/
function _insertBefore(parent, node, child) {
function assertPreInsertionValidity1to5(parent, node, child) {
// 1. If `parent` is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException.
if (!hasValidParentNodeType(parent)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Unexpected parent node type ' + parent.nodeType);
}
// 2. If `node` is a host-including inclusive ancestor of `parent`, then throw a "HierarchyRequestError" DOMException.
// not implemented!
// 3. If `child` is non-null and its parent is not `parent`, then throw a "NotFoundError" DOMException.
if (child && child.parentNode !== parent) {

@@ -757,5 +794,8 @@ throw new DOMException(NOT_FOUND_ERR, 'child not in parent');

if (
// 4. If `node` is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException.
!hasInsertableNodeType(node) ||
// 5. If either `node` is a Text node and `parent` is a document,
// the sax parser currently adds top level text nodes, this will be fixed in 0.9.0
// || (node.nodeType === Node.TEXT_NODE && parent.nodeType === Node.DOCUMENT_NODE)
// or `node` is a doctype and `parent` is not a document, then throw a "HierarchyRequestError" DOMException.
(isDocTypeNode(node) && parent.nodeType !== Node.DOCUMENT_NODE)

@@ -768,33 +808,134 @@ ) {

}
}
/**
* @private
* Step 6 of the checks before inserting and before replacing a child are different.
*
* @param {Document} parent the parent node to insert `node` into
* @param {Node} node the node to insert
* @param {Node | undefined} child the node that should become the `nextSibling` of `node`
* @returns {Node}
* @throws DOMException for several node combinations that would create a DOM that is not well-formed.
* @throws DOMException if `child` is provided but is not a child of `parent`.
* @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
* @see https://dom.spec.whatwg.org/#concept-node-replace
*/
function assertPreInsertionValidityInDocument(parent, node, child) {
var parentChildNodes = parent.childNodes || [];
var nodeChildNodes = node.childNodes || [];
if (parent.nodeType === Node.DOCUMENT_NODE) {
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
var nodeChildElements = nodeChildNodes.filter(isElementNode);
if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment');
}
if (nodeChildElements.length === 1 && !isElementInsertionPossible(parent, child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype');
}
// DocumentFragment
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
var nodeChildElements = nodeChildNodes.filter(isElementNode);
// If node has more than one element child or has a Text node child.
if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment');
}
if (isElementNode(node)) {
if (find(parentChildNodes, isElementNode) || !isElementInsertionPossible(parent, child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype');
}
// Otherwise, if `node` has one element child and either `parent` has an element child,
// `child` is a doctype, or `child` is non-null and a doctype is following `child`.
if (nodeChildElements.length === 1 && !isElementInsertionPossible(parent, child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype');
}
if (isDocTypeNode(node)) {
if (find(parentChildNodes, isDocTypeNode)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed');
}
var parentElementChild = find(parentChildNodes, isElementNode);
if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element');
}
if (!child && parentElementChild) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can not be appended since element is present');
}
}
// Element
if (isElementNode(node)) {
// `parent` has an element child, `child` is a doctype,
// or `child` is non-null and a doctype is following `child`.
if (!isElementInsertionPossible(parent, child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype');
}
}
// DocumentType
if (isDocTypeNode(node)) {
// `parent` has a doctype child,
if (find(parentChildNodes, isDocTypeNode)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed');
}
var parentElementChild = find(parentChildNodes, isElementNode);
// `child` is non-null and an element is preceding `child`,
if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element');
}
// or `child` is null and `parent` has an element child.
if (!child && parentElementChild) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can not be appended since element is present');
}
}
}
/**
* @private
* Step 6 of the checks before inserting and before replacing a child are different.
*
* @param {Document} parent the parent node to insert `node` into
* @param {Node} node the node to insert
* @param {Node | undefined} child the node that should become the `nextSibling` of `node`
* @returns {Node}
* @throws DOMException for several node combinations that would create a DOM that is not well-formed.
* @throws DOMException if `child` is provided but is not a child of `parent`.
* @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
* @see https://dom.spec.whatwg.org/#concept-node-replace
*/
function assertPreReplacementValidityInDocument(parent, node, child) {
var parentChildNodes = parent.childNodes || [];
var nodeChildNodes = node.childNodes || [];
// DocumentFragment
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
var nodeChildElements = nodeChildNodes.filter(isElementNode);
// If `node` has more than one element child or has a Text node child.
if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment');
}
// Otherwise, if `node` has one element child and either `parent` has an element child that is not `child` or a doctype is following `child`.
if (nodeChildElements.length === 1 && !isElementReplacementPossible(parent, child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype');
}
}
// Element
if (isElementNode(node)) {
// `parent` has an element child that is not `child` or a doctype is following `child`.
if (!isElementReplacementPossible(parent, child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype');
}
}
// DocumentType
if (isDocTypeNode(node)) {
function hasDoctypeChildThatIsNotChild(node) {
return isDocTypeNode(node) && node !== child;
}
// `parent` has a doctype child that is not `child`,
if (find(parentChildNodes, hasDoctypeChildThatIsNotChild)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed');
}
var parentElementChild = find(parentChildNodes, isElementNode);
// or an element is preceding `child`.
if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) {
throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element');
}
}
}
/**
* @private
* @param {Node} parent the parent node to insert `node` into
* @param {Node} node the node to insert
* @param {Node=} child the node that should become the `nextSibling` of `node`
* @returns {Node}
* @throws DOMException for several node combinations that would create a DOM that is not well-formed.
* @throws DOMException if `child` is provided but is not a child of `parent`.
* @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
*/
function _insertBefore(parent, node, child, _inDocumentAssertion) {
// To ensure pre-insertion validity of a node into a parent before a child, run these steps:
assertPreInsertionValidity1to5(parent, node, child);
// If parent is a document, and any of the statements below, switched on the interface node implements,
// are true, then throw a "HierarchyRequestError" DOMException.
if (parent.nodeType === Node.DOCUMENT_NODE) {
(_inDocumentAssertion || assertPreInsertionValidityInDocument)(parent, node, child);
}
var cp = node.parentNode;

@@ -840,14 +981,10 @@ if(cp){

function _appendSingleChild(parentNode,newChild){
var cp = newChild.parentNode;
if(cp){
var pre = parentNode.lastChild;
cp.removeChild(newChild);//remove and update
var pre = parentNode.lastChild;
if (newChild.parentNode) {
newChild.parentNode.removeChild(newChild);
}
var pre = parentNode.lastChild;
newChild.parentNode = parentNode;
newChild.previousSibling = pre;
newChild.previousSibling = parentNode.lastChild;
newChild.nextSibling = null;
if(pre){
pre.nextSibling = newChild;
if (newChild.previousSibling) {
newChild.previousSibling.nextSibling = newChild;
}else{

@@ -859,3 +996,2 @@ parentNode.firstChild = newChild;

return newChild;
//console.log("__aa",parentNode.lastChild.nextSibling == null)
}

@@ -901,2 +1037,13 @@

},
replaceChild: function (newChild, oldChild) {
//raises
_insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument);
newChild.ownerDocument = this;
if (oldChild) {
this.removeChild(oldChild);
}
if (isElementNode(newChild)) {
this.documentElement = newChild;
}
},
// Introduced in DOM Level 2:

@@ -903,0 +1050,0 @@ importNode : function(importedNode,deep){

4

package.json
{
"name": "@xmldom/xmldom",
"version": "0.7.8",
"version": "0.7.9",
"description": "A pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module.",

@@ -36,3 +36,3 @@ "keywords": [

"testrelease": "npm test && eslint lib",
"release": "np --no-yarn --test-script testrelease --branch release-0.7.x --tag lts"
"release": "np --no-yarn --test-script testrelease --branch release-0.7.x --tag lts patch"
},

@@ -39,0 +39,0 @@ "engines": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc