From d866db2badd0ebc3447b6916d69e57df0f1999c7 Mon Sep 17 00:00:00 2001 From: raffazizzi Date: Tue, 30 Apr 2024 10:28:00 -0400 Subject: [PATCH] switched to React 16.8-compatible Blockly component. Functional minus the toolbal. Work in progress --- package.json | 6 +- src/components/Blockly.js | 164 +++++++++++++++++++------------------- 2 files changed, 86 insertions(+), 84 deletions(-) diff --git a/package.json b/package.json index 6c99a47..379d3a1 100644 --- a/package.json +++ b/package.json @@ -75,12 +75,9 @@ "html-webpack-plugin": "^2.30.1", "linkedom": "0.14.21", "mocha": "^6.2.0", - "node-blockly": "^1.2.8", "node-sass": "^7.0.3", "react": "^16.9.0", "react-ace": "^7.0.4", - "react-blockly": "^7.0.1", - "react-blockly-component": "3.3.0", "react-dom": "^16.9.0", "react-redux": "^7.1.1", "react-resize-detector": "^4.0.5", @@ -99,5 +96,8 @@ "webpack-dev-middleware": "^1.12.0", "webpack-hot-middleware": "^2.23.1", "xmldom": "^0.6.0" + }, + "dependencies": { + "react-blockly": "^8.1.1" } } diff --git a/src/components/Blockly.js b/src/components/Blockly.js index a0536f2..c2e6cc6 100644 --- a/src/components/Blockly.js +++ b/src/components/Blockly.js @@ -1,12 +1,12 @@ import React, { Component } from 'react' -import ReactBlocklyComponent from 'react-blockly-component' import PropTypes from 'prop-types' -import Blockly from 'node-blockly/browser' import { content, alternate, sequence, elementRef, classRef, dataRef, macroRef, anyElement, empty, textNode } from '../utils/blocks' import ModalPicker from './pickers/ModalPicker' import { Link } from 'react-router-dom' import { _i18n } from '../localization/i18n' +import { BlocklyWorkspace } from 'react-blockly' +import Blockly from 'blockly' const xmlParser = new DOMParser() const xmlSerializer = new XMLSerializer() @@ -15,9 +15,8 @@ export default class BlocklyRomaJsEditor extends Component { constructor(props) { super(props) - window.Blockly = Blockly // TODO: This is bad, find fix. - const thisEditor = this + // FIXME: This isn't running Blockly.FieldDropdown.prototype.showEditor_ = function() { const pickerOptions = [] const opts = Array.from(this.getOptions()) @@ -161,89 +160,87 @@ export default class BlocklyRomaJsEditor extends Component { const i18n = _i18n(this.props.language, 'Blockly') const i18nNotSeeing = _i18n(this.props.language, 'NotSeeingMessage') const config = { - toolboxCategories: [{ - type: 'groups', - name: i18n('Groups'), - colour: '#6da55b', - blocks: [ - { type: 'alternate' }, - { type: 'sequence' }, - ] - }, { - type: 'references', - name: i18n('References'), - colour: '#6d5ba5', - blocks: [ - { type: 'elementRef' }, - { type: 'classRef' }, - { type: 'macroRef' }, - { type: 'dataRef' } - ] - }, { - type: 'nodes', - name: i18n('Nodes'), - colour: '#a55b5b', - blocks: [ - { type: 'anyElement' }, - { type: 'empty' }, - { type: 'textNode' } - ] - }], - initialXml: this.state.initialXml, - wrapperDivClassName: 'romajs-blockly', - workspaceDidChange: function(workspace) { - workspace - }, - xmlDidChange: (xml) => { - const blocklyXml = xmlParser.parseFromString(xml, 'text/xml') - const contentObject = [] - let valid = true - function _processXml(block, curContent) { - const o = {} - const type = block.getAttribute('type') - // Do not update state if alternate|sequence is incomplete - if (type === 'alternate' || type === 'sequence') { - if (!Array.from(block.children).filter(c => c.tagName === 'statement').length > 0) { - valid = false - } + kind: 'categoryToolbox', + contents: [ + { + kind: 'groups', + name: i18n('Groups'), + colour: '#6da55b', + blocks: [ + { type: 'alternate' }, + { type: 'sequence' }, + ] + }, { + kind: 'references', + name: i18n('References'), + colour: '#6d5ba5', + blocks: [ + { type: 'elementRef' }, + { type: 'classRef' }, + { type: 'macroRef' }, + { type: 'dataRef' } + ] + }, { + kind: 'nodes', + name: i18n('Nodes'), + colour: '#a55b5b', + blocks: [ + { type: 'anyElement' }, + { type: 'empty' }, + { type: 'textNode' } + ] + } + ] + } + const handleXmlChange = (xml) => { + const blocklyXml = xmlParser.parseFromString(xml, 'text/xml') + const contentObject = [] + let valid = true + function _processXml(block, curContent) { + const o = {} + const type = block.getAttribute('type') + // Do not update state if alternate|sequence is incomplete + if (type === 'alternate' || type === 'sequence') { + if (!Array.from(block.children).filter(c => c.tagName === 'statement').length > 0) { + valid = false } - for (const blockChild of block.children) { - if (blockChild.tagName === 'field') { - const bName = blockChild.getAttribute('name') - // Do not update state if a key is not set. - if (blockChild.textContent !== '...') { - o[bName] = blockChild.textContent - } else valid = false - // Do no update state if (min|max)Occurs is not valid - if (bName === 'minOccurs' | bName === 'maxOccurs') { - if (!blockChild.textContent.match(/\d+|Infinity/)) { - valid = false - } + } + for (const blockChild of block.children) { + if (blockChild.tagName === 'field') { + const bName = blockChild.getAttribute('name') + // Do not update state if a key is not set. + if (blockChild.textContent !== '...') { + o[bName] = blockChild.textContent + } else valid = false + // Do no update state if (min|max)Occurs is not valid + if (bName === 'minOccurs' | bName === 'maxOccurs') { + if (!blockChild.textContent.match(/\d+|Infinity/)) { + valid = false } - } else if (blockChild.tagName === 'next') { - _processXml(blockChild.querySelector('block'), curContent) - } else if (blockChild.tagName === 'statement') { - o.content = [] - _processXml(blockChild.querySelector('block'), o.content) } + } else if (blockChild.tagName === 'next') { + _processXml(blockChild.querySelector('block'), curContent) + } else if (blockChild.tagName === 'statement') { + o.content = [] + _processXml(blockChild.querySelector('block'), o.content) } - if (valid) { - curContent.unshift(o) - o.type = block.getAttribute('type') - } - return curContent - } - // Only process if there's at least one block - const startBlock = blocklyXml.querySelector("block[type='content'] block") - if (startBlock) { - _processXml(startBlock, contentObject) - } else { - valid = false } - // Now pass this to an action to update content if (valid) { - this.props.updateContentModel(contentObject) + curContent.unshift(o) + o.type = block.getAttribute('type') } + return curContent + } + // Only process if there's at least one block + const startBlock = blocklyXml.querySelector("block[type='content'] block") + if (startBlock) { + _processXml(startBlock, contentObject) + } else { + valid = false + } + // Now pass this to an action to update content + if (valid) { + this.props.updateContentModel(contentObject) } } const msg = ({i18nNotSeeing('q')}  @@ -255,7 +252,12 @@ export default class BlocklyRomaJsEditor extends Component { this.setState({pickerVisible: false}) this.state.pickerAdd(i) }} message={msg} language={this.props.language}/> - {React.createElement(ReactBlocklyComponent.BlocklyEditor, config)} + ) } }