diff --git a/core/block_events.js b/core/block_events.js
index b40316871..0af3b9e4c 100644
--- a/core/block_events.js
+++ b/core/block_events.js
@@ -197,9 +197,8 @@ Blockly.Events.Change.prototype.run = function(forward) {
oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom);
}
if (block.domToMutation) {
- value = value || '';
- var dom = Blockly.Xml.textToDom('' + value + '');
- block.domToMutation(dom.firstChild);
+ var dom = Blockly.Xml.textToDom(value || '');
+ block.domToMutation(dom);
}
Blockly.Events.fire(new Blockly.Events.Change(
block, 'mutation', null, oldMutation, value));
@@ -261,7 +260,7 @@ Blockly.Events.Create.prototype.toJson = function() {
*/
Blockly.Events.Create.prototype.fromJson = function(json) {
Blockly.Events.Create.superClass_.fromJson.call(this, json);
- this.xml = Blockly.Xml.textToDom('' + json['xml'] + '').firstChild;
+ this.xml = Blockly.Xml.textToDom(json['xml']);
this.ids = json['ids'];
};
diff --git a/core/options.js b/core/options.js
index 3775f2dcb..d584ae86d 100644
--- a/core/options.js
+++ b/core/options.js
@@ -26,8 +26,9 @@
goog.provide('Blockly.Options');
-goog.require('Blockly.Xml');
goog.require('Blockly.Themes.Classic');
+goog.require('Blockly.utils.userAgent');
+goog.require('Blockly.Xml');
/**
@@ -48,7 +49,8 @@ Blockly.Options = function(options) {
var hasDisable = false;
var hasSounds = false;
} else {
- var languageTree = Blockly.Options.parseToolboxTree(options['toolbox']);
+ var languageTree =
+ Blockly.Options.parseToolboxTree(options['toolbox'] || null);
var hasCategories = Boolean(languageTree &&
languageTree.getElementsByTagName('category').length);
var hasTrashcan = options['trashcan'];
@@ -263,11 +265,11 @@ Blockly.Options.parseGridOptions_ = function(options) {
Blockly.Options.parseToolboxTree = function(tree) {
if (tree) {
if (typeof tree != 'string') {
- if (typeof XSLTProcessor == 'undefined' && tree.outerHTML) {
+ if (Blockly.utils.userAgent.IE && tree.outerHTML) {
// In this case the tree will not have been properly built by the
// browser. The HTML will be contained in the element, but it will
// not have the proper DOM structure since the browser doesn't support
- // XSLTProcessor (XML -> HTML). This is the case in IE 9+.
+ // XSLTProcessor (XML -> HTML).
tree = tree.outerHTML;
} else if (!(tree instanceof Element)) {
tree = null;
@@ -275,6 +277,9 @@ Blockly.Options.parseToolboxTree = function(tree) {
}
if (typeof tree == 'string') {
tree = Blockly.Xml.textToDom(tree);
+ if (tree.nodeName.toLowerCase() != 'xml') {
+ throw TypeError('Toolbox should be an document.');
+ }
}
} else {
tree = null;
diff --git a/core/trashcan.js b/core/trashcan.js
index 956c21e43..8ab4c0e7b 100644
--- a/core/trashcan.js
+++ b/core/trashcan.js
@@ -431,7 +431,7 @@ Blockly.Trashcan.prototype.click = function() {
var xml = [];
for (var i = 0, text; text = this.contents_[i]; i++) {
- xml[i] = Blockly.Xml.textToDom(text).firstChild;
+ xml[i] = Blockly.Xml.textToDom(text);
}
this.flyout_.show(xml);
};
@@ -531,5 +531,5 @@ Blockly.Trashcan.prototype.cleanBlockXML_ = function(xml) {
}
node = nextNode;
}
- return '' + Blockly.Xml.domToText(xmlBlock) + '';
+ return Blockly.Xml.domToText(xmlBlock);
};
diff --git a/core/variables.js b/core/variables.js
index f002e2ca7..da4773710 100644
--- a/core/variables.js
+++ b/core/variables.js
@@ -175,39 +175,33 @@ Blockly.Variables.flyoutCategoryBlocks = function(workspace) {
variableModelList[variableModelList.length - 1]);
if (Blockly.Blocks['variables_set']) {
var gap = Blockly.Blocks['math_change'] ? 8 : 24;
- var blockText = '' +
- '' +
+ var blockText = '' +
mostRecentVariableFieldXmlString +
- '' +
- '';
- var block = Blockly.Xml.textToDom(blockText).firstChild;
+ '';
+ var block = Blockly.Xml.textToDom(blockText);
xmlList.push(block);
}
if (Blockly.Blocks['math_change']) {
var gap = Blockly.Blocks['variables_get'] ? 20 : 8;
- var blockText = '' +
- '' +
+ var blockText = '' +
mostRecentVariableFieldXmlString +
'' +
'' +
'1' +
'' +
'' +
- '' +
- '';
- var block = Blockly.Xml.textToDom(blockText).firstChild;
+ '';
+ var block = Blockly.Xml.textToDom(blockText);
xmlList.push(block);
}
if (Blockly.Blocks['variables_get']) {
variableModelList.sort(Blockly.VariableModel.compareByName);
for (var i = 0, variable; variable = variableModelList[i]; i++) {
- var blockText = '' +
- '' +
+ var blockText = '' +
Blockly.Variables.generateVariableFieldXmlString(variable) +
- '' +
- '';
- var block = Blockly.Xml.textToDom(blockText).firstChild;
+ '';
+ var block = Blockly.Xml.textToDom(blockText);
xmlList.push(block);
}
}
@@ -481,10 +475,7 @@ Blockly.Variables.generateVariableFieldXmlString = function(variableModel) {
Blockly.Variables.generateVariableFieldDom = function(variableModel) {
var xmlFieldString =
Blockly.Variables.generateVariableFieldXmlString(variableModel);
- var text = '' + xmlFieldString + '';
- var dom = Blockly.Xml.textToDom(text);
- var fieldDom = dom.firstChild;
- return fieldDom;
+ return Blockly.Xml.textToDom(xmlFieldString);
};
/**
diff --git a/core/variables_dynamic.js b/core/variables_dynamic.js
index cc95e2b3e..1408faf92 100644
--- a/core/variables_dynamic.js
+++ b/core/variables_dynamic.js
@@ -93,23 +93,19 @@ Blockly.VariablesDynamic.flyoutCategoryBlocks = function(workspace) {
if (Blockly.Blocks['variables_set_dynamic']) {
var firstVariable = variableModelList[variableModelList.length - 1];
var gap = 24;
- var blockText = '' +
- '' +
+ var blockText = '' +
Blockly.Variables.generateVariableFieldXmlString(firstVariable) +
- '' +
- '';
- var block = Blockly.Xml.textToDom(blockText).firstChild;
+ '';
+ var block = Blockly.Xml.textToDom(blockText);
xmlList.push(block);
}
if (Blockly.Blocks['variables_get_dynamic']) {
variableModelList.sort(Blockly.VariableModel.compareByName);
for (var i = 0, variable; variable = variableModelList[i]; i++) {
- var blockText = '' +
- '' +
+ var blockText = '' +
Blockly.Variables.generateVariableFieldXmlString(variable) +
- '' +
- '';
- var block = Blockly.Xml.textToDom(blockText).firstChild;
+ '';
+ var block = Blockly.Xml.textToDom(blockText);
xmlList.push(block);
}
}
diff --git a/core/xml.js b/core/xml.js
index c8fb003e5..6bced0fd0 100644
--- a/core/xml.js
+++ b/core/xml.js
@@ -317,20 +317,17 @@ Blockly.Xml.domToPrettyText = function(dom) {
};
/**
- * Converts an XML string into a DOM structure. It requires the XML to have a
- * root element of . Other XML string will result in throwing an error.
+ * Converts an XML string into a DOM structure.
* @param {string} text An XML string.
* @return {!Element} A DOM object representing the singular child of the
* document element.
- * @throws if XML doesn't parse or is not the expected structure.
+ * @throws if the text doesn't parse.
*/
Blockly.Xml.textToDom = function(text) {
var doc = Blockly.Xml.utils.textToDomDocument(text);
- // This function only accepts documents.
if (!doc || !doc.documentElement ||
- doc.documentElement.nodeName.toLowerCase() != 'xml') {
- // Whatever we got back from the parser is not the expected structure.
- throw TypeError('Blockly.Xml.textToDom expected an document.');
+ doc.getElementsByTagName('parsererror').length) {
+ throw Error('textToDom was unable to parse: ' + text);
}
return doc.documentElement;
};
diff --git a/tests/mocha/trashcan_test.js b/tests/mocha/trashcan_test.js
index d1ce4c36b..b284e43e0 100644
--- a/tests/mocha/trashcan_test.js
+++ b/tests/mocha/trashcan_test.js
@@ -287,9 +287,7 @@ suite("Trashcan", function() {
test("Max 0", function() {
workspace.options.maxTrashcanContents = 0;
sendDeleteEvent(
- '' +
- ' ' +
- ''
+ ''
);
chai.assert.equal(this.trashcan.contents_.length, 0);
workspace.options.maxTrashcanContents = Infinity;
@@ -301,7 +299,7 @@ suite("Trashcan", function() {
chai.assert.equal(this.trashcan.contents_.length, 1);
chai.assert.equal(
Blockly.Xml.textToDom(this.trashcan.contents_[0])
- .children[0].getAttribute('type'),
+ .getAttribute('type'),
'dummy_type2'
);
workspace.options.maxTrashcanContents = Infinity;