node-blockly
node-blockly copied to clipboard
Blocks do not always translate
You can reproduce this in your live demo, http://mo4islona.github.io/blockly/
First, load the page and change the language to french. Open the the Loops flyout to see that the while block has been translated to french. Then close the flyout and translate back to english. Check the Loops flyout again and still see french in the While block.
It seems like these blocks are getting stuck on whatever language they are set to when you first look at them.
I've got a hacky way I think I can fix this in my own fork of node-blockly. I'm not sure how what the correct way to fix this is yet.
I know about this problem and think the problem is inside Blockly. Some blocks translates back correctly some not. For example Test translates correctly in english after french.
They fixed some blocks – in earlier versions of Blockly no one blocks translated back.
Ah yea... At first I thought it was only drop downs but now I see its all pretty random. I'll take a look at blockly at some point and see if I can do a PR there.
For the time being I'm working around this in my application by creating a blocklyStore.js
:
module.exports = {
Blockly: require('node-blockly/browser'),
reset: function() {
delete require.cache[require.resolve('node-blockly/browser')]
delete require.cache[require.resolve('node-blockly/lib/blockly_compressed_browser')]
delete require.cache[require.resolve('node-blockly/lib/blocks_compressed_browser')]
this.Blockly = require('node-blockly/browser')
},
}
Then to use Blockly I do:
var BS = require('blocklyStore')
BS.Blockly.inject(...
Then whenever I change languages I call BS.reset()
.
This seems to work fine as a work around for now.
Turns out my work around wasn't quite enough...
This line causes problems.. https://github.com/mo4islona/node-blockly/blob/master/browser.js#L12
Since setLocale
is always called initially with english, so even when you clear the require cache it still gets called with english from the start and that messes up some blocks.
I'm not sure if my current solution is good enough for a PR, but I changed browser.js to this
var getBlockly = function(languageCode) {
delete require.cache[require.resolve('node-blockly/lib/blockly_compressed_browser')]
delete require.cache[require.resolve('node-blockly/lib/blocks_compressed_browser')]
var Blockly = require('./lib/blockly_compressed_browser');
Blockly._setLocale = function(locale) {
Blockly.Msg = Object.assign(locale, Blockly.Msg);
Blockly.Msg = Blockly.Msg();
}
Blockly.utils.getMessageArray_ = function () {
return Blockly.Msg
}
Blockly._setLocale(require('./lib/i18n/' + languageCode))
Blockly.Blocks = Object.assign(Blockly.Blocks, require('./lib/blocks_compressed_browser')(Blockly));
Blockly.JavaScript = require('./lib/javascript_compressed')(Blockly);
Blockly.Lua = require('./lib/lua_compressed')(Blockly);
Blockly.Dart = require('./lib/dart_compressed')(Blockly);
Blockly.PHP = require('./lib/php_compressed')(Blockly);
Blockly.Python = require('./lib/python_compressed')(Blockly);
return Blockly
}
class Blockly {
constructor() {
Object.assign(this, getBlockly('en'))
}
setLanguage = (languageCode) => {
Object.assign(this, getBlockly(languageCode))
}
}
module.exports = new Blockly()
Then, to change the language I do this
import Blockly from 'node-blockly/browser'
var changeLanguage = (languageCode) => {
Blockly.setLanguage(languageCode)
var currentXML = this._getWorkspaceXML()
this._workspace.dispose()
this._workspace = Blockly.inject(config.blocklyElementId, {
toolbox: getToolbox(this._appManager),
grid: config.blocklyGridOptions,
})
this._setWorkspaceXML(currentXML)
}
With this solution, Blockly._setLocale
only ever gets called on a given instance of Blockly
once.
But this solution is nice because I can change the language without doing the weird cache invalidation in my own code.
If I made a PR using this pattern and cleaned it up some keeping Blockly.setLocale
as the public method, I don't think it would break existing code that uses setLocale
? Let me know if you're interested in a PR with this pattern.