mirror of
https://github.com/google/blockly.git
synced 2026-01-21 07:47:09 +01:00
Support XML serialization in Node.js (#3126)
* Support XML serialization in Node.js
This commit is contained in:
@@ -43,7 +43,8 @@ Blockly.Events.fromJson=function(a,b){switch(a.type){case Blockly.Events.CREATE:
|
||||
new Blockly.Events.VarRename(null,"");break;case Blockly.Events.UI:c=new Blockly.Events.Ui(null);break;case Blockly.Events.COMMENT_CREATE:c=new Blockly.Events.CommentCreate(null);break;case Blockly.Events.COMMENT_CHANGE:c=new Blockly.Events.CommentChange(null);break;case Blockly.Events.COMMENT_MOVE:c=new Blockly.Events.CommentMove(null);break;case Blockly.Events.COMMENT_DELETE:c=new Blockly.Events.CommentDelete(null);break;default:throw Error("Unknown event type.");}c.fromJson(a);c.workspaceId=b.id;
|
||||
return c};Blockly.Events.disableOrphans=function(a){if(a.type==Blockly.Events.MOVE||a.type==Blockly.Events.CREATE){var b=Blockly.Workspace.getById(a.workspaceId);if(a=b.getBlockById(a.blockId)){var c=a.getParent();if(c&&c.isEnabled())for(b=a.getDescendants(!1),a=0;c=b[a];a++)c.setEnabled(!0);else if((a.outputConnection||a.previousConnection)&&!b.isDragging()){do a.setEnabled(!1),a=a.getNextBlock();while(a)}}}};
|
||||
Blockly.Events.Abstract=function(){this.workspaceId=void 0;this.group=Blockly.Events.group_;this.recordUndo=Blockly.Events.recordUndo};Blockly.Events.Abstract.prototype.toJson=function(){var a={type:this.type};this.group&&(a.group=this.group);return a};Blockly.Events.Abstract.prototype.fromJson=function(a){this.group=a.group};Blockly.Events.Abstract.prototype.isNull=function(){return!1};Blockly.Events.Abstract.prototype.run=function(a){};
|
||||
Blockly.Events.Abstract.prototype.getEventWorkspace_=function(){var a=Blockly.Workspace.getById(this.workspaceId);if(!a)throw Error("Workspace is null. Event must have been generated from real Blockly events.");return a};Blockly.utils.object={};Blockly.utils.object.inherits=function(a,b){a.superClass_=b.prototype;a.prototype=Object.create(b.prototype);a.prototype.constructor=a};Blockly.utils.object.mixin=function(a,b){for(var c in b)a[c]=b[c]};Blockly.utils.object.values=function(a){return Object.values?Object.values(a):Object.keys(a).map(function(b){return a[b]})};Blockly.utils.xml={};Blockly.utils.xml.NAME_SPACE="https://developers.google.com/blockly/xml";Blockly.utils.xml.createElement=function(a){return document.createElementNS(Blockly.utils.xml.NAME_SPACE,a)};Blockly.utils.xml.createTextNode=function(a){return document.createTextNode(a)};Blockly.utils.xml.textToDomDocument=function(a){return(new DOMParser).parseFromString(a,"text/xml")};Blockly.utils.xml.domToText=function(a){return(new XMLSerializer).serializeToString(a)};Blockly.Events.BlockBase=function(a){Blockly.Events.BlockBase.superClass_.constructor.call(this);this.blockId=a.id;this.workspaceId=a.workspace.id};Blockly.utils.object.inherits(Blockly.Events.BlockBase,Blockly.Events.Abstract);Blockly.Events.BlockBase.prototype.toJson=function(){var a=Blockly.Events.BlockBase.superClass_.toJson.call(this);a.blockId=this.blockId;return a};
|
||||
Blockly.Events.Abstract.prototype.getEventWorkspace_=function(){var a=Blockly.Workspace.getById(this.workspaceId);if(!a)throw Error("Workspace is null. Event must have been generated from real Blockly events.");return a};Blockly.utils.object={};Blockly.utils.object.inherits=function(a,b){a.superClass_=b.prototype;a.prototype=Object.create(b.prototype);a.prototype.constructor=a};Blockly.utils.object.mixin=function(a,b){for(var c in b)a[c]=b[c]};Blockly.utils.object.values=function(a){return Object.values?Object.values(a):Object.keys(a).map(function(b){return a[b]})};Blockly.utils.xml={};Blockly.utils.xml.NAME_SPACE="https://developers.google.com/blockly/xml";Blockly.utils.xml.document=function(){return document};Blockly.utils.xml.createElement=function(a){return Blockly.utils.xml.document().createElementNS(Blockly.utils.xml.NAME_SPACE,a)};Blockly.utils.xml.createTextNode=function(a){return Blockly.utils.xml.document().createTextNode(a)};Blockly.utils.xml.textToDomDocument=function(a){return(new DOMParser).parseFromString(a,"text/xml")};
|
||||
Blockly.utils.xml.domToText=function(a){return(new XMLSerializer).serializeToString(a)};Blockly.Events.BlockBase=function(a){Blockly.Events.BlockBase.superClass_.constructor.call(this);this.blockId=a.id;this.workspaceId=a.workspace.id};Blockly.utils.object.inherits(Blockly.Events.BlockBase,Blockly.Events.Abstract);Blockly.Events.BlockBase.prototype.toJson=function(){var a=Blockly.Events.BlockBase.superClass_.toJson.call(this);a.blockId=this.blockId;return a};
|
||||
Blockly.Events.BlockBase.prototype.fromJson=function(a){Blockly.Events.BlockBase.superClass_.fromJson.call(this,a);this.blockId=a.blockId};Blockly.Events.Change=function(a,b,c,d,e){a&&(Blockly.Events.Change.superClass_.constructor.call(this,a),this.element=b,this.name=c,this.oldValue=d,this.newValue=e)};Blockly.utils.object.inherits(Blockly.Events.Change,Blockly.Events.BlockBase);Blockly.Events.BlockChange=Blockly.Events.Change;Blockly.Events.Change.prototype.type=Blockly.Events.CHANGE;
|
||||
Blockly.Events.Change.prototype.toJson=function(){var a=Blockly.Events.Change.superClass_.toJson.call(this);a.element=this.element;this.name&&(a.name=this.name);a.newValue=this.newValue;return a};Blockly.Events.Change.prototype.fromJson=function(a){Blockly.Events.Change.superClass_.fromJson.call(this,a);this.element=a.element;this.name=a.name;this.newValue=a.newValue};Blockly.Events.Change.prototype.isNull=function(){return this.oldValue==this.newValue};
|
||||
Blockly.Events.Change.prototype.run=function(a){var b=this.getEventWorkspace_().getBlockById(this.blockId);if(b)switch(b.mutator&&b.mutator.setVisible(!1),a=a?this.newValue:this.oldValue,this.element){case "field":(b=b.getField(this.name))?b.setValue(a):console.warn("Can't set non-existent field: "+this.name);break;case "comment":b.setCommentText(a||null);break;case "collapsed":b.setCollapsed(a);break;case "disabled":b.setEnabled(!a);break;case "inline":b.setInputsInline(a);break;case "mutation":var c=
|
||||
|
||||
@@ -37,6 +37,16 @@ goog.provide('Blockly.utils.xml');
|
||||
*/
|
||||
Blockly.utils.xml.NAME_SPACE = 'https://developers.google.com/blockly/xml';
|
||||
|
||||
/**
|
||||
* Get the document object. This method is overridden in the Node.js build of
|
||||
* Blockly. See gulpfile.js, package-blockly-node task.
|
||||
* @return {!Document} The document object.
|
||||
* @public
|
||||
*/
|
||||
Blockly.utils.xml.document = function() {
|
||||
return document;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create DOM element for XML.
|
||||
* @param {string} tagName Name of DOM element.
|
||||
@@ -44,8 +54,8 @@ Blockly.utils.xml.NAME_SPACE = 'https://developers.google.com/blockly/xml';
|
||||
* @public
|
||||
*/
|
||||
Blockly.utils.xml.createElement = function(tagName) {
|
||||
// TODO (#2082): Support node.js.
|
||||
return document.createElementNS(Blockly.utils.xml.NAME_SPACE, tagName);
|
||||
return Blockly.utils.xml.document().createElementNS(
|
||||
Blockly.utils.xml.NAME_SPACE, tagName);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -55,13 +65,11 @@ Blockly.utils.xml.createElement = function(tagName) {
|
||||
* @public
|
||||
*/
|
||||
Blockly.utils.xml.createTextNode = function(text) {
|
||||
// TODO (#2082): Support node.js.
|
||||
return document.createTextNode(text);
|
||||
return Blockly.utils.xml.document().createTextNode(text);
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts an XML string into a DOM tree. This method will be overridden in
|
||||
* the Node.js build of Blockly. See gulpfile.js, blockly_javascript_en task.
|
||||
* Converts an XML string into a DOM tree.
|
||||
* @param {string} text XML string.
|
||||
* @return {Document} The DOM document.
|
||||
* @throws if XML doesn't parse.
|
||||
@@ -80,7 +88,6 @@ Blockly.utils.xml.textToDomDocument = function(text) {
|
||||
* @public
|
||||
*/
|
||||
Blockly.utils.xml.domToText = function(dom) {
|
||||
// TODO (#2082): Support node.js.
|
||||
var oSerializer = new XMLSerializer();
|
||||
return oSerializer.serializeToString(dom);
|
||||
};
|
||||
|
||||
13
gulpfile.js
13
gulpfile.js
@@ -453,13 +453,12 @@ gulp.task('package-blockly-node', function() {
|
||||
return gulp.src('blockly_compressed.js')
|
||||
.pipe(gulp.insert.append(`
|
||||
if (typeof DOMParser !== 'function') {
|
||||
var JSDOM = require('jsdom').JSDOM;
|
||||
var window = (new JSDOM()).window;
|
||||
var document = window.document;
|
||||
var Element = window.Element;
|
||||
Blockly.utils.xml.textToDomDocument = function(text) {
|
||||
var jsdom = new JSDOM(text, { contentType: 'text/xml' });
|
||||
return jsdom.window.document;
|
||||
var DOMParser = require("jsdom/lib/jsdom/living").DOMParser;
|
||||
var XMLSerializer = require("jsdom/lib/jsdom/living").XMLSerializer;
|
||||
var doc = Blockly.utils.xml.textToDomDocument(
|
||||
'<xml xmlns="https://developers.google.com/blockly/xml"></xml>');
|
||||
Blockly.utils.xml.document = function() {
|
||||
return doc;
|
||||
};
|
||||
}`))
|
||||
.pipe(packageCommonJS('Blockly', []))
|
||||
|
||||
@@ -26,25 +26,33 @@ var assert = require('chai').assert;
|
||||
var Blockly = require('../../dist/');
|
||||
|
||||
var xmlText = `<xml xmlns="https://developers.google.com/blockly/xml">
|
||||
<block type="text_print" x="37" y="63">
|
||||
<value name="TEXT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">Hello from Blockly!</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="text_print" x="37" y="63">
|
||||
<value name="TEXT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">Hello from Blockly!</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</xml>`;
|
||||
|
||||
suite('Test Node.js', function() {
|
||||
test('Import XML', function() {
|
||||
assert.doesNotThrow(function() {
|
||||
const xml = Blockly.Xml.textToDom(xmlText);
|
||||
const xml = Blockly.Xml.textToDom(xmlText);
|
||||
|
||||
// Create workspace and import the XML
|
||||
const workspace = new Blockly.Workspace();
|
||||
Blockly.Xml.domToWorkspace(xml, workspace);
|
||||
// Create workspace and import the XML
|
||||
const workspace = new Blockly.Workspace();
|
||||
Blockly.Xml.domToWorkspace(xml, workspace);
|
||||
});
|
||||
test('Roundtrip XML', function() {
|
||||
const xml = Blockly.Xml.textToDom(xmlText);
|
||||
|
||||
}, "Failed to import XML");
|
||||
const workspace = new Blockly.Workspace();
|
||||
Blockly.Xml.domToWorkspace(xml, workspace);
|
||||
|
||||
var headlessXml = Blockly.Xml.workspaceToDom(workspace, true);
|
||||
var headlessText = Blockly.Xml.domToPrettyText(headlessXml);
|
||||
|
||||
assert.equal(headlessText, xmlText, 'equal');
|
||||
});
|
||||
test('Generate Code', function() {
|
||||
const xml = Blockly.Xml.textToDom(xmlText);
|
||||
|
||||
Reference in New Issue
Block a user