Fixed Block Factory XML not Getting Properly Cleaned (#2801)

* Fixed factory XML not getting properly cleaned.

* Added jsdoc.
This commit is contained in:
Beka Westberg
2019-08-21 15:59:21 -07:00
committed by Neil Fraser
parent aa3925c8dc
commit 33e6fa6ed9

View File

@@ -921,12 +921,12 @@ FactoryUtils.sameBlockXml = function(blockXml1, blockXml2) {
// Each XML element should contain a single child element with a 'block' tag // Each XML element should contain a single child element with a 'block' tag
if (blockXml1.tagName.toLowerCase() != 'xml' || if (blockXml1.tagName.toLowerCase() != 'xml' ||
blockXml2.tagName.toLowerCase() != 'xml') { blockXml2.tagName.toLowerCase() != 'xml') {
throw new Error('Expected two XML elements, recieved elements with tag ' + throw new Error('Expected two XML elements, received elements with tag ' +
'names: ' + blockXml1.tagName + ' and ' + blockXml2.tagName + '.'); 'names: ' + blockXml1.tagName + ' and ' + blockXml2.tagName + '.');
} }
// Compare the block elements directly. The XML tags may include other meta // Compare the block elements directly. The XML tags may include other meta
// information we want to igrore. // information we want to ignore.
var blockElement1 = blockXml1.getElementsByTagName('block')[0]; var blockElement1 = blockXml1.getElementsByTagName('block')[0];
var blockElement2 = blockXml2.getElementsByTagName('block')[0]; var blockElement2 = blockXml2.getElementsByTagName('block')[0];
@@ -934,8 +934,11 @@ FactoryUtils.sameBlockXml = function(blockXml1, blockXml2) {
throw new Error('Could not get find block element in XML.'); throw new Error('Could not get find block element in XML.');
} }
var blockXmlText1 = Blockly.Xml.domToText(blockElement1); var cleanBlockXml1 = FactoryUtils.cleanXml(blockElement1);
var blockXmlText2 = Blockly.Xml.domToText(blockElement2); var cleanBlockXml2 = FactoryUtils.cleanXml(blockElement2);
var blockXmlText1 = Blockly.Xml.domToText(cleanBlockXml1);
var blockXmlText2 = Blockly.Xml.domToText(cleanBlockXml2);
// Strip white space. // Strip white space.
blockXmlText1 = blockXmlText1.replace(/\s+/g, ''); blockXmlText1 = blockXmlText1.replace(/\s+/g, '');
@@ -945,6 +948,47 @@ FactoryUtils.sameBlockXml = function(blockXml1, blockXml2) {
return blockXmlText1 == blockXmlText2; return blockXmlText1 == blockXmlText2;
}; };
/**
* Strips the provided xml of any attributes that don't describe the
* 'structure' of the blocks (i.e. block order, field values, etc).
* @param {Node} xml The xml to clean.
* @return {Node}
*/
FactoryUtils.cleanXml = function(xml) {
var newXml = xml.cloneNode(true);
var node = newXml;
while (node) {
// Things like text inside tags are still treated as nodes, but they
// don't have attributes (or the removeAttribute function) so we can
// skip removing attributes from them.
if (node.removeAttribute) {
node.removeAttribute('xmlns');
node.removeAttribute('x');
node.removeAttribute('y');
node.removeAttribute('id');
}
// Try to go down the tree
var nextNode = node.firstChild || node.nextSibling;
// If we can't go down, try to go back up the tree.
if (!nextNode) {
nextNode = node.parentNode;
while (nextNode) {
// We are valid again!
if (nextNode.nextSibling) {
nextNode = nextNode.nextSibling;
break;
}
// Try going up again. If parentNode is null that means we have
// reached the top, and we will break out of both loops.
nextNode = nextNode.parentNode;
}
}
node = nextNode;
}
return newXml;
};
/* /*
* Checks if a block has a variable field. Blocks with variable fields cannot * Checks if a block has a variable field. Blocks with variable fields cannot
* be shadow blocks. * be shadow blocks.