Blockly.Extensions.buildTooltipForDropdown(..): Deferred validation. (#870)

Defer tooltip message string check until after load, when all Blockly.Msg should be loaded.
Avoids validation in headless mode, due to lack of document.readyState.
This commit is contained in:
Andrew n marshall
2017-01-26 15:12:32 -08:00
committed by GitHub
parent 5891288d60
commit 624afeee94
2 changed files with 34 additions and 4 deletions

View File

@@ -88,16 +88,23 @@ Blockly.Extensions.buildTooltipForDropdown = function(dropdownName, lookupTable)
// List of block types already validated, to minimize duplicate warnings.
var blockTypesChecked = [];
// Validate message strings early.
for (var key in lookupTable) {
Blockly.utils.checkMessageReferences(lookupTable[key]);
// Check the tooltip string messages for invalid references.
// Wait for load, in case Blockly.Msg is not yet populated.
// runAfterPageLoad() does not run in a Node.js environment due to lack of
// document object, in which case skip the validation.
if (document) { // Relies on document.readyState
Blockly.utils.runAfterPageLoad(function() {
for (var key in lookupTable) {
Blockly.utils.checkMessageReferences(lookupTable[key]);
}
});
}
/**
* The actual extension.
* @this {Blockly.Block}
*/
return function() {
var extensionFn = function() {
var thisBlock = this;
if (this.type && !blockTypesChecked.includes(this.type)) {
@@ -125,6 +132,7 @@ Blockly.Extensions.buildTooltipForDropdown = function(dropdownName, lookupTable)
return tooltip;
});
};
return extensionFn;
};
/**

View File

@@ -834,3 +834,25 @@ Blockly.utils.insertAfter_ = function(newNode, refNode) {
parentNode.appendChild(newNode);
}
};
/**
* Calls a function after the page has loaded, possibly immediately.
* @param {function()} fn Function to run.
* @throws Error Will throw if no global document can be found (e.g., Node.js).
*/
Blockly.utils.runAfterPageLoad = function(fn) {
if (!document) {
throw new Error('Blockly.utils.runAfterPageLoad() requires browser document.');
}
if (document.readyState === 'complete') {
fn(); // Page has already loaded. Call immediately.
} else {
// Poll readyState.
var readyStateCheckInterval = setInterval(function() {
if (document.readyState === 'complete') {
clearInterval(readyStateCheckInterval);
fn();
}
}, 10);
}
};