Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(tests): Fix bootstrapping of generators in compressed mode #6703

Merged
merged 1 commit into from
Dec 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions tests/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,34 @@
'dist/python_compressed.js',
],

// List of imports to give global names to. The keys are the
// global variable names, the values are goog.module IDs to name,
// or (when loading in compressed mode) the paths within the
// Blockly namespace at which the corresponding chunk is loaded by
// its UMD wrapper. Note that entries in this map are ignored if
// the corresponding goog.module has not been loaded via an entry
// in requires or compressedScripts.
namedImports: {
Blockly: 'Blockly',
libraryBlocks: 'Blockly.libraryBlocks',
},

// List of destructured imports. As for namedImports, but only
// the named export corresponding to the mentioned global variable
// will be imported.
//
// Exception: in compressed mode, the UMD wrapeprs generated by
// chunkWrapper() in scripts/gulpfiles/build_tasks.js already pull
// out the desired named export - so in that case the entries here
// are treated identically to those in namedImports.
destructuredImports: {
dartGenerator: 'Blockly.Dart',
javascriptGenerator: 'Blockly.JavaScript',
luaGenerator: 'Blockly.Lua',
phpGenerator: 'Blockly.PHP',
pythonGenerator: 'Blockly.Python',
},

// Additional scripts to be loaded after Blockly is loaded,
// whether Blockly is loaded from compressed or uncompressed.
// Paths relative to root.
Expand All @@ -117,6 +145,8 @@
window.bootstrapInfo = {
/** boolean */ compressed: options.loadCompressed,
/** ?Array<string> */ requires: null,
/** Object<string> */ namedImports: options.namedImports,
/** Object<string> */ destructuredImports: options.destructuredImports,
/** ?Promise */ done: null,
};

Expand Down Expand Up @@ -188,8 +218,11 @@
} else {
// We need to load Blockly in compressed mode. Load
// blockly_compressed.js et al. using <script> tags.
const scripts =
[...options.compressedScripts, ...options.additionalScripts];
const scripts = [
...options.compressedScripts,
'tests/bootstrap_helper.js',
...options.additionalScripts,
];
for (const script of scripts) {
document.write(`<script src="${options.root + script}"></script>`);
}
Expand Down
80 changes: 55 additions & 25 deletions tests/bootstrap_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,60 @@
* undeclared dependencies on them.
*/

/* eslint-disable-next-line no-undef */
for (const require of window.bootstrapInfo.requires) {
goog.require(require);
(function() {
const info = window.bootstrapInfo;

// If require is a top-level chunk, create a global variable for it.
// This replaces the goog.module.declareLegacyNamespace calls that
// previously existed in each chunk entrypoint.
const exportName = {
'Blockly.Dart': 'dartGenerator',
'Blockly.Dart.all': 'dartGenerator',
'Blockly.JavaScript': 'javascriptGenerator',
'Blockly.JavaScript.all': 'javascriptGenerator',
'Blockly.Lua': 'luaGenerator',
'Blockly.Lua.all': 'luaGenerator',
'Blockly.PHP': 'phpGenerator',
'Blockly.PHP.all': 'phpGenerator',
'Blockly.Python': 'pythonGenerator',
'Blockly.Python.all': 'pythonGenerator',
}[require];
if (exportName) {
window[exportName] = goog.module.get(require)[exportName];
} else if (require === 'Blockly') {
window.Blockly = goog.module.get(require);
} else if (require === 'Blockly.libraryBlocks') {
window.libraryBlocks = goog.module.get(require);
if (!info.compressed) {
// Force debug module loader to finish loading all modules.
for (const require of info.requires) {
goog.require(require);

// This is a kludge to work around an issue where attempting to
// load Blockly.libraryBlocks (blocks/blocks.js) fails if the
// Blockly global variable is not defined.
//
// This is apparently because the debug module loader fails to
// load Blockly.libraryBlocks.lists (blocks/lists.js) and
// .procedures (blocks/procedures.js) first, despite they both
// being required from blocks.js, and that is apparently because
// they both depend on Blockly.Xml which the debug loader seems
// to think has not been loaded yet even though it has.
if (require === 'Blockly') {
window.Blockly = goog.module.get('Blockly');
}
}
}

// Create global names for named and destructured imports.
for (const varName in info.namedImports) {
const id = info.namedImports[varName];
const value = info.compressed ? get(id) : goog.module.get(id);
if (value) {
window[varName] = value;
}
}
for (const varName in info.destructuredImports) {
const id = info.destructuredImports[varName];
const value = info.compressed ? get(id) : goog.module.get(id)[varName];
if (value) {
window[varName] = value;
}
}

return; // All done. Only helper functions after this point.

/**
* Get the object referred to by a doted-itentifier path
* (e.g. foo.bar.baz).
* @param {string} path The path referring to the object.
* @return {string|null} The object, or null if not found.
*/
function get(path) {
let obj = window;
for (const part of path.split('.')) {
obj = obj[part];
if (!obj) return null;
}
return obj;
}
}
})();