forked from google/blockly
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(tests): Use
goog.bootstrap
to allow loading ES modules in …
…playground (google#5931) * chore(deps): Update closure/goog/base.js, add goog.js * Update base.js from the latest version (20220104.0.0). * Also copy over goog.js, which provides access to asuitable subset of goog.* via an importable module). * refactor(tests): Have playground.html load Blockly as a module N.B.: * We still need a preparation step, in order to load base.js and deps.js via <script> tags in uncompiled mode; in compiled mode it will instead load all the *_compressed.js files via <script> tags. Acess to the Blockly object is via: import Blockly from './playgrounds/blockly.mjs'; (N.B: no "* as", since blockly.mjs has only a default export.) * There remain two serious defects when running in uncompiled mode: * It does not attempt to load msg/messages.js, causing startup to fail. * Module loading only works if there are no ES Modules; if there are, something goes wrong with base.js's attempt to sequence module loads causing goog.modules that import ES modules to get a null exports object for that import. X-( * fix(tests): Have playground.html load messages.js before generators This fixes the issue caused by missing messages when loading the generators. * fix(tests): Move bootsrap calls to prepare.js Move the calls to goog.bootstrap from blockly.mjs to prepare.mjs. This is needed to work around a bug in the Cosure Library debug loader (google/closure-library#1152). This gets a bit ugly because most of the code has to go in a <script> (because it needs goog.bootstrap, which was loaded by an earlier <script> tag). * fix(documentation): Minor comment corrections for PR google#5931
- Loading branch information
Showing
6 changed files
with
249 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// Copyright 2018 The Closure Library Authors. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS-IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
/** | ||
* @fileoverview ES6 module that exports symbols from base.js so that ES6 | ||
* modules do not need to use globals and so that is clear if a project is using | ||
* Closure's base.js file. It is also a subset of properties in base.js, meaning | ||
* it should be clearer what should not be used in ES6 modules | ||
* (goog.module/provide are not exported here, for example). Though that is not | ||
* to say that everything in this file should be used in an ES6 module; some | ||
* depreciated functions are exported to make migration easier (e.g. | ||
* goog.scope). | ||
* | ||
* Note that this does not load Closure's base.js file, it is still up to the | ||
* programmer to include it. Nor does the fact that this is an ES6 module mean | ||
* that projects no longer require deps.js files for debug loading - they do. | ||
* Closure will need to load your ES6 modules for you if you have any Closure | ||
* file (goog.provide/goog.module) dependencies, as they need to be available | ||
* before the ES6 module evaluates. | ||
* | ||
* Also note that this file has special compiler handling! It is okay to export | ||
* anything from this file, but the name also needs to exist on the global goog. | ||
* This special compiler pass enforces that you always import this file as | ||
* `import * as goog`, as many tools use regex based parsing to find | ||
* goog.require calls. | ||
*/ | ||
|
||
export const global = goog.global; | ||
export const require = goog.require; | ||
export const define = goog.define; | ||
export const DEBUG = goog.DEBUG; | ||
export const LOCALE = goog.LOCALE; | ||
export const TRUSTED_SITE = goog.TRUSTED_SITE; | ||
export const DISALLOW_TEST_ONLY_CODE = goog.DISALLOW_TEST_ONLY_CODE; | ||
export const getGoogModule = goog.module.get; | ||
export const setTestOnly = goog.setTestOnly; | ||
export const forwardDeclare = goog.forwardDeclare; | ||
export const getObjectByName = goog.getObjectByName; | ||
export const basePath = goog.basePath; | ||
export const addSingletonGetter = goog.addSingletonGetter; | ||
export const typeOf = goog.typeOf; | ||
export const isArrayLike = goog.isArrayLike; | ||
export const isDateLike = goog.isDateLike; | ||
export const isObject = goog.isObject; | ||
export const getUid = goog.getUid; | ||
export const hasUid = goog.hasUid; | ||
export const removeUid = goog.removeUid; | ||
export const mixin = goog.mixin; | ||
export const now = Date.now; | ||
export const globalEval = goog.globalEval; | ||
export const getCssName = goog.getCssName; | ||
export const setCssNameMapping = goog.setCssNameMapping; | ||
export const getMsg = goog.getMsg; | ||
export const getMsgWithFallback = goog.getMsgWithFallback; | ||
export const exportSymbol = goog.exportSymbol; | ||
export const exportProperty = goog.exportProperty; | ||
export const nullFunction = goog.nullFunction; | ||
export const abstractMethod = goog.abstractMethod; | ||
export const cloneObject = goog.cloneObject; | ||
export const bind = goog.bind; | ||
export const partial = goog.partial; | ||
export const inherits = goog.inherits; | ||
export const scope = goog.scope; | ||
export const defineClass = goog.defineClass; | ||
export const declareModuleId = goog.declareModuleId; | ||
|
||
// Export select properties of module. Do not export the function itself or | ||
// goog.module.declareLegacyNamespace. | ||
export const module = { | ||
get: goog.module.get, | ||
}; | ||
|
||
// Omissions include: | ||
// goog.ENABLE_DEBUG_LOADER - define only used in base. | ||
// goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING - define only used in base. | ||
// goog.provide - ES6 modules do not provide anything. | ||
// goog.module - ES6 modules cannot be goog.modules. | ||
// goog.module.declareLegacyNamespace - ES6 modules cannot declare namespaces. | ||
// goog.addDependency - meant to only be used by dependency files. | ||
// goog.DEPENDENCIES_ENABLED - constant only used in base. | ||
// goog.TRANSPILE - define only used in base. | ||
// goog.TRANSPILER - define only used in base. | ||
// goog.loadModule - should not be called by any ES6 module; exists for | ||
// generated bundles. | ||
// goog.LOAD_MODULE_USING_EVAL - define only used in base. | ||
// goog.SEAL_MODULE_EXPORTS - define only used in base. | ||
// goog.DebugLoader - used rarely, only outside of compiled code. | ||
// goog.Transpiler - used rarely, only outside of compiled code. |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/** | ||
* @license | ||
* Copyright 2022 Google LLC | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/** | ||
* @fileoverview Finishes loading Blockly and exports it as this | ||
* module's default export. | ||
* | ||
* It is exported as the default export to avoid having to | ||
* re-export each property on Blockly individually, because you | ||
* can't do: | ||
* | ||
* export * from <dynamically computed source>; // SYNTAX ERROR | ||
* | ||
* You must use a <script> tag to load prepare.js first, before | ||
* importing this module in a <script type=module> to obtain the | ||
* loaded value. | ||
* | ||
* See tests/playground.html for example usage. | ||
*/ | ||
|
||
let Blockly; | ||
|
||
if (window.BlocklyLoader) { | ||
// Uncompiled mode. Use top-level await | ||
// (https://v8.dev/features/top-level-await) to block loading of | ||
// this module until goog.bootstrap()ping of Blockly is finished. | ||
Blockly = await window.BlocklyLoader; | ||
} else if (window.Blockly) { | ||
// Compiled mode. Retrieve the pre-installed Blockly global. | ||
Blockly = globalThis.Blockly; | ||
} else { | ||
throw new Error('neither window.Blockly nor window.BlocklyLoader found'); | ||
} | ||
|
||
export default Blockly; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/** | ||
* @license | ||
* Copyright 2021 Google LLC | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/** | ||
* @fileoverview Load this file in a <script> tag to prepare for | ||
* importing Blockly into a web page. | ||
* | ||
* You must use a <script> tag to load this script first, then | ||
* import blockly.mjs in a <script type=module> to obtain the | ||
* loaded value. | ||
* | ||
* See tests/playground.html for example usage. | ||
*/ | ||
'use strict'; | ||
|
||
(function() { | ||
// Decide whether we can load Blockly uncompiled, or must load the | ||
// compiled version. Please see issue #5557 for more information. | ||
const isIe = navigator.userAgent.indexOf('MSIE') !== -1 || | ||
navigator.appVersion.indexOf('Trident/') > -1; | ||
const localhosts = ['localhost', '127.0.0.1', '[::1]']; | ||
|
||
if (localhosts.includes(location.hostname) && !isIe) { | ||
// We can load Blockly in uncompiled mode. | ||
|
||
// Disable loading of closure/goog/deps.js (which doesn't exist). | ||
window.CLOSURE_NO_DEPS = true; | ||
// Load the Closure Library's base.js (the only part of the | ||
// libary we use, mainly for goog.require / goog.provide / | ||
// goog.module). | ||
document.write('<script src="../../closure/goog/base.js"></script>'); | ||
// Load dependency graph info from test/deps.js. To update | ||
// deps.js, run `npm run build:deps`. | ||
document.write('<script src="../../tests/deps.js"></script>'); | ||
|
||
// Msg loading kludge. This should go away once #5409 and/or | ||
// #1895 are fixed. | ||
|
||
// Load messages into a temporary Blockly.Msg object, deleting it | ||
// afterwards (after saving the messages!) | ||
window.Blockly = {Msg: Object.create(null)}; | ||
document.write('<script src="../../msg/messages.js"></script>'); | ||
document.write(` | ||
<script> | ||
window.BlocklyMsg = window.Blockly.Msg; | ||
delete window.Blockly; | ||
</script>`); | ||
|
||
document.write(` | ||
<script> | ||
window.BlocklyLoader = new Promise((resolve, reject) => { | ||
goog.bootstrap( | ||
[ | ||
'Blockly', | ||
'Blockly.blocks.all', | ||
'Blockly.Dart.all', | ||
'Blockly.JavaScript.all', | ||
'Blockly.Lua.all', | ||
'Blockly.PHP.all', | ||
'Blockly.Python.all', | ||
], resolve); | ||
}).then(() => { | ||
// Copy Messages from temporary Blockly.Msg object to the real one: | ||
Object.assign(goog.module.get('Blockly').Msg, window.BlocklyMsg); | ||
}).then(() => { | ||
return goog.module.get('Blockly'); | ||
}); | ||
</script>`); | ||
} else { | ||
// We need to load Blockly in compiled mode. | ||
|
||
// Load blockly_compressed.js et al. using <script> tags. | ||
document.write('<script src="../../blockly_compressed.js"></script>'); | ||
document.write('<script src="../../dart_compressed.js"></script>'); | ||
document.write('<script src="../../javascript_compressed.js"></script>'); | ||
document.write('<script src="../../lua_compressed.js"></script>'); | ||
document.write('<script src="../../php_compressed.js"></script>'); | ||
document.write('<script src="../../python_compressed.js"></script>'); | ||
document.write('<script src="../../blocks_compressed.js"></script>'); | ||
document.write('<script src="../../msg/messages.js"></script>'); | ||
} | ||
})(); |