Migrate core.global.js to named exports (#5451)

This is part of #5153 but is being prioritised because we want remove
the declareLegacyNamespace calls from the core/utils/*.js modules and
then reexport them explicitly via utils.js, and it turns out that
doing so results in the exports object of this module being passed to
Object.freeze - which fails on the global object, which can't be made
non-extensible!

The new name chosen for the former default export is globalThis, since
it is intended to have the same value as the global variable of that
name; see:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis
This commit is contained in:
Christopher Allen
2021-09-14 14:39:29 +01:00
committed by GitHub
parent 09fb59f6ee
commit f9d0caa112
11 changed files with 38 additions and 33 deletions

View File

@@ -14,7 +14,7 @@ goog.module('Blockly.browserEvents');
goog.module.declareLegacyNamespace();
const Touch = goog.require('Blockly.Touch');
const global = goog.require('Blockly.utils.global');
const {globalThis} = goog.require('Blockly.utils.global');
/**
@@ -69,7 +69,7 @@ const conditionalBind = function(
};
const bindData = [];
if (global['PointerEvent'] && (name in Touch.TOUCH_MAP)) {
if (globalThis['PointerEvent'] && (name in Touch.TOUCH_MAP)) {
for (let i = 0; i < Touch.TOUCH_MAP[name].length; i++) {
const type = Touch.TOUCH_MAP[name][i];
node.addEventListener(type, wrapFunc, false);
@@ -124,7 +124,7 @@ const bind = function(node, name, thisObject, func) {
};
const bindData = [];
if (global['PointerEvent'] && (name in Touch.TOUCH_MAP)) {
if (globalThis['PointerEvent'] && (name in Touch.TOUCH_MAP)) {
for (let i = 0; i < Touch.TOUCH_MAP[name].length; i++) {
const type = Touch.TOUCH_MAP[name][i];
node.addEventListener(type, wrapFunc, false);

View File

@@ -17,16 +17,16 @@
goog.module('Blockly.Msg');
goog.module.declareLegacyNamespace();
const global = goog.require('Blockly.utils.global');
const {globalThis} = goog.require('Blockly.utils.global');
/**
* Exported so that if Blockly is compiled with ADVANCED_COMPILATION,
* the Blockly.Msg object exists for message files included in script tags.
*/
if (!global['Blockly']) {
global['Blockly'] = {};
if (!globalThis['Blockly']) {
globalThis['Blockly'] = {};
}
if (!global['Blockly']['Msg']) {
global['Blockly']['Msg'] = exports;
if (!globalThis['Blockly']['Msg']) {
globalThis['Blockly']['Msg'] = exports;
}

View File

@@ -16,7 +16,7 @@ goog.module.declareLegacyNamespace();
/* eslint-disable-next-line no-unused-vars */
const Gesture = goog.requireType('Blockly.Gesture');
const internalConstants = goog.require('Blockly.internalConstants');
const utilsGlobal = goog.require('Blockly.utils.global');
const {globalThis} = goog.require('Blockly.utils.global');
const utilsString = goog.require('Blockly.utils.string');
@@ -26,13 +26,13 @@ const utilsString = goog.require('Blockly.utils.string');
* @const
*/
const TOUCH_ENABLED =
('ontouchstart' in utilsGlobal ||
!!(utilsGlobal['document'] && document.documentElement &&
('ontouchstart' in globalThis ||
!!(globalThis['document'] && document.documentElement &&
'ontouchstart' in document.documentElement) ||
// IE10 uses non-standard touch events, so it has a different check.
!!(utilsGlobal['navigator'] &&
(utilsGlobal['navigator']['maxTouchPoints'] ||
utilsGlobal['navigator']['msMaxTouchPoints'])));
!!(globalThis['navigator'] &&
(globalThis['navigator']['maxTouchPoints'] ||
globalThis['navigator']['msMaxTouchPoints'])));
exports.TOUCH_ENABLED = TOUCH_ENABLED;
/**
@@ -47,7 +47,7 @@ let touchIdentifier_ = null;
* @type {Object}
*/
let TOUCH_MAP = {};
if (utilsGlobal['PointerEvent']) {
if (globalThis['PointerEvent']) {
TOUCH_MAP = {
'mousedown': ['pointerdown'],
'mouseenter': ['pointerenter'],

View File

@@ -28,7 +28,7 @@ const Rect = goog.require('Blockly.utils.Rect');
const WorkspaceSvg = goog.requireType('Blockly.WorkspaceSvg');
const colourUtils = goog.require('Blockly.utils.colour');
const deprecation = goog.require('Blockly.utils.deprecation');
const global = goog.require('Blockly.utils.global');
const {globalThis} = goog.require('Blockly.utils.global');
const idGenerator = goog.require('Blockly.utils.idGenerator');
const internalConstants = goog.require('Blockly.internalConstants');
const stringUtils = goog.require('Blockly.utils.string');
@@ -433,7 +433,7 @@ const is3dSupported = function() {
}
// CC-BY-SA Lorenzo Polidori
// stackoverflow.com/questions/5661671/detecting-transform-translate3d-support
if (!global['getComputedStyle']) {
if (!globalThis['getComputedStyle']) {
return false;
}
@@ -453,7 +453,7 @@ const is3dSupported = function() {
for (let t in transforms) {
if (el.style[t] !== undefined) {
el.style[t] = 'translate3d(1px,1px,1px)';
const computedStyle = global['getComputedStyle'](el);
const computedStyle = globalThis['getComputedStyle'](el);
if (!computedStyle) {
// getComputedStyle in Firefox returns null when Blockly is loaded
// inside an iframe with display: none. Returning false and not

View File

@@ -20,7 +20,10 @@ goog.module.declareLegacyNamespace();
* More info on this implementation here:
* https://docs.google.com/document/d/1NAeW4Wk7I7FV0Y2tcUFvQdGMc89k2vdgSXInw8_nvCI
*/
const utilsGlobal = function() {
exports.globalThis = (function() { // Not "let globalThis" to avoid shadowing.
if (typeof globalThis === 'object') {
return globalThis;
}
if (typeof self === 'object') {
return self;
}
@@ -31,6 +34,4 @@ const utilsGlobal = function() {
return global;
}
return this;
}();
exports = utilsGlobal;
})();

View File

@@ -19,7 +19,7 @@
goog.module('Blockly.utils.userAgent');
goog.module.declareLegacyNamespace();
const global = goog.require('Blockly.utils.global');
const {globalThis} = goog.require('Blockly.utils.global');
/**
@@ -100,7 +100,7 @@ isGecko = has('Gecko') && !isWebKit && !isIe && !isEdge;
// https://github.com/google/closure-library/blob/master/closure/goog/labs/useragent/extra.js
isAndroid = has('Android');
const maxTouchPoints =
global['navigator'] && global['navigator']['maxTouchPoints'];
globalThis['navigator'] && globalThis['navigator']['maxTouchPoints'];
isIPad = has('iPad') || has('Macintosh') && maxTouchPoints > 0;
isIPod = has('iPod');
isIPhone = has('iPhone') && !isIPad && !isIPod;
@@ -110,7 +110,7 @@ isMac = has('Macintosh');
// https://github.com/google/closure-library/blob/master/closure/goog/labs/useragent/device.js
isTablet = isIPad || (isAndroid && !has('Mobile')) || has('Silk');
isMobile = !isTablet && (isIPod || isIPhone || isAndroid || has('IEMobile'));
})((global['navigator'] && global['navigator']['userAgent']) || '');
})((globalThis['navigator'] && globalThis['navigator']['userAgent']) || '');
/** @const {string} */
exports.raw = rawUserAgent;

View File

@@ -16,7 +16,7 @@ goog.module.declareLegacyNamespace();
/* eslint-disable-next-line no-unused-vars */
const WorkspaceSvg = goog.requireType('Blockly.WorkspaceSvg');
const global = goog.require('Blockly.utils.global');
const {globalThis} = goog.require('Blockly.utils.global');
const internalConstants = goog.require('Blockly.internalConstants');
const userAgent = goog.require('Blockly.utils.userAgent');
@@ -72,7 +72,7 @@ WorkspaceAudio.prototype.load = function(filenames, name) {
}
let audioTest;
try {
audioTest = new global['Audio']();
audioTest = new globalThis['Audio']();
} catch (e) {
// No browser support for Audio.
// IE can throw an error even if the Audio object exists.
@@ -84,7 +84,7 @@ WorkspaceAudio.prototype.load = function(filenames, name) {
const ext = filename.match(/\.(\w+)$/);
if (ext && audioTest.canPlayType('audio/' + ext[1])) {
// Found an audio format we can play.
sound = new global['Audio'](filename);
sound = new globalThis['Audio'](filename);
break;
}
}

View File

@@ -42,7 +42,7 @@ Blockly.JavaScript.addReservedWords(
// Magic variable.
'arguments,' +
// Everything in the current environment (835 items in Chrome, 104 in Node).
Object.getOwnPropertyNames(Blockly.utils.global).join(','));
Object.getOwnPropertyNames(Blockly.utils.global.globalThis).join(','));
/**
* Order of operation ENUMs.

View File

@@ -72,6 +72,9 @@ const renamings = {
genUid: {module: 'Blockly.utils.idGenerator'},
}
},
'Blockly.utils.global': {
export: 'globalThis', // Previous default export now named.
},
'Blockly.utils.IdGenerator': {
module: 'Blockly.utils.idGenerator',
}

View File

@@ -22,9 +22,10 @@ Blockly.setLocale = function (locale) {
// Override textToDomDocument and provide Node.js alternatives to DOMParser and
// XMLSerializer.
if (typeof Blockly.utils.global.document !== 'object') {
Blockly.utils.global.DOMParser = require('jsdom/lib/jsdom/living').DOMParser;
Blockly.utils.global.XMLSerializer = require('jsdom/lib/jsdom/living').XMLSerializer;
const globalThis = Blockly.utils.global.globalThis;
if (typeof globalThis.document !== 'object') {
globalThis.DOMParser = require('jsdom/lib/jsdom/living').DOMParser;
globalThis.XMLSerializer = require('jsdom/lib/jsdom/living').XMLSerializer;
var doc = Blockly.utils.xml.textToDomDocument(
'<xml xmlns="https://developers.google.com/blockly/xml"></xml>');
Blockly.utils.xml.document = function() {

View File

@@ -215,7 +215,7 @@ goog.addDependency('../../core/utils/colour.js', ['Blockly.utils.colour'], [], {
goog.addDependency('../../core/utils/coordinate.js', ['Blockly.utils.Coordinate'], [], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/utils/deprecation.js', ['Blockly.utils.deprecation'], [], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/utils/dom.js', ['Blockly.utils.dom'], ['Blockly.utils.userAgent'], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/utils/global.js', ['Blockly.utils.global'], [], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/utils/global.js', ['Blockly.utils.global'], [], {'module': 'goog'});
goog.addDependency('../../core/utils/idgenerator.js', ['Blockly.utils.idGenerator'], [], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/utils/keycodes.js', ['Blockly.utils.KeyCodes'], [], {'lang': 'es6', 'module': 'goog'});
goog.addDependency('../../core/utils/math.js', ['Blockly.utils.math'], [], {'lang': 'es6', 'module': 'goog'});