Blockly简介
Blockly是一个将可视代码编辑器添加到Web和移动应用程序的库。 Blockly 编辑器使用互锁的图形块来表示代码概念,如变量,逻辑表达式,循环等。它使得用户可以不必关注语法细节就能直接按照编程原则进行编程。 中文文档(blockly.tortorse.com/guides/over… ps:文档写的很烂,学习的话建议下载源码结合起来看。
遇到的问题
正常来讲,如果某个block被禁用了,那说明这个block就不需要转代码,当然Blockly内部也是这么做的,但我们的需求是要把它按正常的保留下来。
解决思路
最先想到的肯定就是去翻文档了,但是找了半天,并没有找到相关的配置。 那就只能看源码了,
//Blockly源码
workspaceToCode(workspace?: Workspace): string {
.....
for (let i = 0, block; (block = blocks[i]); i++) {
let line = this.blockToCode(block);
}
......
}
可以看到在源码里workspaceToCode方法中调用一个this.blockToCode方法。我们顺着看下这个方法
//Blockly源码
blockToCode(
block: Block | null,
opt_thisOnly?: boolean,
): string | [string, number] {
.....
if (!block.isEnabled()) {
// Skip past this block if it is disabled.
return opt_thisOnly ? '' : this.blockToCode(block.getNextBlock());
}
.....
}
看到这里原因就很明显啦,主要是这个判断“if (!block.isEnabled())”。那最简单的方式就是直接重写一个blockToCode方法覆盖掉Blockly实例上的方法,然后把block.isEnabled()这个判断去掉就好。
//项目中的代码。
//我直接从浏览器里复制了打包后的代码blockToCode。
(Blockly as any).JavaScript.blockToCode = function (a: any, b: any) {
false === this.isInitialized && console.warn("Generator init was not called before blockToCode was called.");
if (!a)
return "";
if (a.isInsertionMarker())
return b ? "" : this.blockToCode(a.getChildren(false)[0]);
let c = this[a.type];
if ("function" != typeof c)
throw Error('Language "' + this.name_ + '" does not know how to generate code for block type "' + a.type + '".');
c = c.call(a, a);
if (Array.isArray(c)) {
if (!a.outputConnection)
throw TypeError("Expecting string from statement block: " + a.type);
return [this.scrub_(a, c[0], b), c[1]];
}
if ("string" == typeof c)
return this.STATEMENT_PREFIX && !a.suppressPrefixSuffix && (c = this.injectId(this.STATEMENT_PREFIX, a) + c), this.STATEMENT_SUFFIX && !a.suppressPrefixSuffix && (c += this.injectId(this.STATEMENT_SUFFIX, a)), this.scrub_(a, c, b);
if (null === c)
return "";
throw SyntaxError("Invalid code generated: " + c);
}
OK那这个问题就被解决啦。