Skip to content

Commit

Permalink
switched to React 16.8-compatible Blockly component. Functional minus…
Browse files Browse the repository at this point in the history
… the toolbal. Work in progress
  • Loading branch information
raffazizzi committed Apr 30, 2024
1 parent caf7510 commit d866db2
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 84 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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"
}
}
164 changes: 83 additions & 81 deletions src/components/Blockly.js
Original file line number Diff line number Diff line change
@@ -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()
Expand All @@ -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())
Expand Down Expand Up @@ -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 = (<span>{i18nNotSeeing('q')}&nbsp;
Expand All @@ -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)}
<BlocklyWorkspace
className="romajs-blockly"
toolboxConfiguration={config} // this must be a JSON toolbox definition
initialXml={this.state.initialXml}
onXmlChange={handleXmlChange}
/>
</div>)
}
}
Expand Down

0 comments on commit d866db2

Please sign in to comment.