mirror of
https://github.com/google/blockly.git
synced 2026-01-07 17:10:11 +01:00
Use null-prototype objects for maps
A {} has a bunch of names already defined on it (like ‘toString’). When using an object as a map with arbitrary keys, it should not inherit from Object.prototype.
This commit is contained in:
2
build.py
2
build.py
@@ -135,7 +135,7 @@ this.BLOCKLY_BOOT = function(root) {
|
||||
|
||||
f.write('\n')
|
||||
f.write('// Load Blockly.\n')
|
||||
f.write('goog.require(\'Blockly.requires\')\n')
|
||||
f.write('goog.require(\'Blockly.requires\');\n')
|
||||
|
||||
f.write("""
|
||||
delete root.BLOCKLY_DIR;
|
||||
|
||||
@@ -28,14 +28,14 @@ Blockly.ComponentManager = function() {
|
||||
* @type {!Object<string, !Blockly.ComponentManager.ComponentDatum>}
|
||||
* @private
|
||||
*/
|
||||
this.componentData_ = {};
|
||||
this.componentData_ = Object.create(null);
|
||||
|
||||
/**
|
||||
* A map of capabilities to component ids.
|
||||
* @type {!Object<string, Array<string>>}
|
||||
* A map of capabilities to component IDs.
|
||||
* @type {!Object<string, !Array<string>>}
|
||||
* @private
|
||||
*/
|
||||
this.capabilityToComponentIds_ = {};
|
||||
this.capabilityToComponentIds_ = Object.create(null);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,11 +31,11 @@ Blockly.ContextMenuRegistry = function() {
|
||||
Blockly.ContextMenuRegistry.registry = this;
|
||||
|
||||
/**
|
||||
* Registry of all registered RegistryItems, keyed by id.
|
||||
* @type {!Object<string, Blockly.ContextMenuRegistry.RegistryItem>}
|
||||
* Registry of all registered RegistryItems, keyed by ID.
|
||||
* @type {!Object<string, !Blockly.ContextMenuRegistry.RegistryItem>}
|
||||
* @private
|
||||
*/
|
||||
this.registry_ = {};
|
||||
this.registry_ = Object.create(null);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -97,7 +97,7 @@ Blockly.ContextMenuRegistry.registry = null;
|
||||
*/
|
||||
Blockly.ContextMenuRegistry.prototype.register = function(item) {
|
||||
if (this.registry_[item.id]) {
|
||||
throw Error('Menu item with id "' + item.id + '" is already registered.');
|
||||
throw Error('Menu item with ID "' + item.id + '" is already registered.');
|
||||
}
|
||||
this.registry_[item.id] = item;
|
||||
};
|
||||
@@ -108,11 +108,10 @@ Blockly.ContextMenuRegistry.prototype.register = function(item) {
|
||||
* @throws {Error} if an item with the given ID does not exist.
|
||||
*/
|
||||
Blockly.ContextMenuRegistry.prototype.unregister = function(id) {
|
||||
if (this.registry_[id]) {
|
||||
delete this.registry_[id];
|
||||
} else {
|
||||
throw new Error('Menu item with id "' + id + '" not found.');
|
||||
if (!this.registry_[id]) {
|
||||
throw new Error('Menu item with ID "' + id + '" not found.');
|
||||
}
|
||||
delete this.registry_[id];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -120,10 +119,7 @@ Blockly.ContextMenuRegistry.prototype.unregister = function(id) {
|
||||
* @return {?Blockly.ContextMenuRegistry.RegistryItem} RegistryItem or null if not found
|
||||
*/
|
||||
Blockly.ContextMenuRegistry.prototype.getItem = function(id) {
|
||||
if (this.registry_[id]) {
|
||||
return this.registry_[id];
|
||||
}
|
||||
return null;
|
||||
return this.registry_[id] || null;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,7 @@ goog.requireType('Blockly.Block');
|
||||
* The set of all registered extensions, keyed by extension name/id.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Extensions.ALL_ = {};
|
||||
Blockly.Extensions.ALL_ = Object.create(null);
|
||||
|
||||
/**
|
||||
* Registers a new extension function. Extensions are functions that help
|
||||
|
||||
@@ -228,5 +228,6 @@ Blockly.Names.prototype.safeName_ = function(name) {
|
||||
* @return {boolean} True if names are the same.
|
||||
*/
|
||||
Blockly.Names.equals = function(name1, name2) {
|
||||
// name1.localeCompare(name2) is slower.
|
||||
return name1.toLowerCase() == name2.toLowerCase();
|
||||
};
|
||||
|
||||
@@ -404,7 +404,7 @@ Blockly.Procedures.getDefinition = function(name, workspace) {
|
||||
blocks[i]);
|
||||
var tuple = procedureBlock.getProcedureDef();
|
||||
if (tuple && Blockly.Names.equals(tuple[0], name)) {
|
||||
return blocks[i];
|
||||
return procedureBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ goog.requireType('Blockly.ToolboxItem');
|
||||
*
|
||||
* @type {Object<string, Object<string, function(new:?)>>}
|
||||
*/
|
||||
Blockly.registry.typeMap_ = {};
|
||||
Blockly.registry.typeMap_ = Object.create(null);
|
||||
|
||||
/**
|
||||
* The string used to register the default class for a type of plugin.
|
||||
@@ -137,7 +137,7 @@ Blockly.registry.register = function(
|
||||
var typeRegistry = Blockly.registry.typeMap_[type];
|
||||
// If the type registry has not been created, create it.
|
||||
if (!typeRegistry) {
|
||||
typeRegistry = Blockly.registry.typeMap_[type] = {};
|
||||
typeRegistry = Blockly.registry.typeMap_[type] = Object.create(null);
|
||||
}
|
||||
|
||||
// Validate that the given class has all the required properties.
|
||||
|
||||
@@ -587,10 +587,10 @@ Blockly.blockRendering.ConstantProvider.prototype.setTheme = function(
|
||||
|
||||
/**
|
||||
* The block styles map.
|
||||
* @type {Object<string, Blockly.Theme.BlockStyle>}
|
||||
* @type {Object<string, !Blockly.Theme.BlockStyle>}
|
||||
* @package
|
||||
*/
|
||||
this.blockStyles = {};
|
||||
this.blockStyles = Object.create(null);
|
||||
|
||||
var blockStyles = theme.blockStyles;
|
||||
for (var key in blockStyles) {
|
||||
|
||||
@@ -45,17 +45,17 @@ Blockly.zelos.PathObject = function(root, style, constants) {
|
||||
|
||||
/**
|
||||
* The selected path of the block.
|
||||
* @type {SVGElement}
|
||||
* @type {?SVGElement}
|
||||
* @private
|
||||
*/
|
||||
this.svgPathSelected_ = null;
|
||||
|
||||
/**
|
||||
* The outline paths on the block.
|
||||
* @type {!Object<string,!SVGElement>}
|
||||
* @type {!Object<string, !SVGElement>}
|
||||
* @private
|
||||
*/
|
||||
this.outlines_ = {};
|
||||
this.outlines_ = Object.create(null);
|
||||
|
||||
/**
|
||||
* A set used to determine which outlines were used during a draw pass. The
|
||||
@@ -98,8 +98,7 @@ Blockly.zelos.PathObject.prototype.applyColour = function(block) {
|
||||
}
|
||||
|
||||
// Apply colour to outlines.
|
||||
for (var i = 0, keys = Object.keys(this.outlines_),
|
||||
key; (key = keys[i]); i++) {
|
||||
for (var key in this.outlines_) {
|
||||
this.outlines_[key].setAttribute('fill', this.style.colourTertiary);
|
||||
}
|
||||
};
|
||||
@@ -110,8 +109,7 @@ Blockly.zelos.PathObject.prototype.applyColour = function(block) {
|
||||
Blockly.zelos.PathObject.prototype.flipRTL = function() {
|
||||
Blockly.zelos.PathObject.superClass_.flipRTL.call(this);
|
||||
// Mirror each input outline path.
|
||||
for (var i = 0, keys = Object.keys(this.outlines_),
|
||||
key; (key = keys[i]); i++) {
|
||||
for (var key in this.outlines_) {
|
||||
this.outlines_[key].setAttribute('transform', 'scale(-1 1)');
|
||||
}
|
||||
};
|
||||
@@ -175,9 +173,8 @@ Blockly.zelos.PathObject.prototype.updateShapeForInputHighlight = function(
|
||||
* @package
|
||||
*/
|
||||
Blockly.zelos.PathObject.prototype.beginDrawing = function() {
|
||||
this.remainingOutlines_ = {};
|
||||
for (var i = 0, keys = Object.keys(this.outlines_),
|
||||
key; (key = keys[i]); i++) {
|
||||
this.remainingOutlines_ = Object.create(null);
|
||||
for (var key in this.outlines_) {
|
||||
// The value set here isn't used anywhere, we are just using the
|
||||
// object as a Set data structure.
|
||||
this.remainingOutlines_[key] = 1;
|
||||
@@ -192,8 +189,7 @@ Blockly.zelos.PathObject.prototype.endDrawing = function() {
|
||||
// Go through all remaining outlines that were not used this draw pass, and
|
||||
// remove them.
|
||||
if (this.remainingOutlines_) {
|
||||
for (var i = 0, keys = Object.keys(this.remainingOutlines_),
|
||||
key; (key = keys[i]); i++) {
|
||||
for (var key in this.remainingOutlines_) {
|
||||
this.removeOutlinePath_(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,10 +125,10 @@ Blockly.Toolbox = function(workspace) {
|
||||
|
||||
/**
|
||||
* A map from toolbox item IDs to toolbox items.
|
||||
* @type {!Object<string, Blockly.IToolboxItem>}
|
||||
* @type {!Object<string, !Blockly.IToolboxItem>}
|
||||
* @protected
|
||||
*/
|
||||
this.contentMap_ = {};
|
||||
this.contentMap_ = Object.create(null);
|
||||
|
||||
/**
|
||||
* Position of the toolbox and flyout relative to the workspace.
|
||||
@@ -393,7 +393,7 @@ Blockly.Toolbox.prototype.render = function(toolboxDef) {
|
||||
}
|
||||
}
|
||||
this.contents_ = [];
|
||||
this.contentMap_ = {};
|
||||
this.contentMap_ = Object.create(null);
|
||||
this.renderContents_(toolboxDef['contents']);
|
||||
this.position();
|
||||
};
|
||||
@@ -537,7 +537,7 @@ Blockly.Toolbox.prototype.getClientRect = function() {
|
||||
* @public
|
||||
*/
|
||||
Blockly.Toolbox.prototype.getToolboxItemById = function(id) {
|
||||
return this.contentMap_[id];
|
||||
return this.contentMap_[id] || null;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -411,11 +411,7 @@ Blockly.Trashcan.prototype.openFlyout = function() {
|
||||
if (this.contentsIsOpen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var xml = [];
|
||||
for (var i = 0, text; (text = this.contents_[i]); i++) {
|
||||
xml[i] = Blockly.Xml.textToDom(text);
|
||||
}
|
||||
var xml = this.contents_.map(Blockly.Xml.textToDom);
|
||||
this.flyout.show(xml);
|
||||
this.fireUiEvent_(true);
|
||||
};
|
||||
@@ -427,7 +423,6 @@ Blockly.Trashcan.prototype.closeFlyout = function() {
|
||||
if (!this.contentsIsOpen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.flyout.hide();
|
||||
this.fireUiEvent_(false);
|
||||
};
|
||||
|
||||
@@ -232,7 +232,7 @@ Blockly.utils.dom.setCssTransform = function(element, transform) {
|
||||
Blockly.utils.dom.startTextWidthCache = function() {
|
||||
Blockly.utils.dom.cacheReference_++;
|
||||
if (!Blockly.utils.dom.cacheWidths_) {
|
||||
Blockly.utils.dom.cacheWidths_ = {};
|
||||
Blockly.utils.dom.cacheWidths_ = Object.create(null);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -353,7 +353,7 @@ Blockly.utils.toolbox.xmlToJsonArray_ = function(toolboxDef) {
|
||||
obj['contents'] = Blockly.utils.toolbox.xmlToJsonArray_(child);
|
||||
}
|
||||
|
||||
// Add xml attributes to object
|
||||
// Add XML attributes to object
|
||||
Blockly.utils.toolbox.addAttributes_(child, obj);
|
||||
arr.push(obj);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ Blockly.Warning = function(block) {
|
||||
Blockly.Warning.superClass_.constructor.call(this, block);
|
||||
this.createIcon();
|
||||
// The text_ object can contain multiple warnings.
|
||||
this.text_ = {};
|
||||
this.text_ = Object.create(null);
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.Warning, Blockly.Icon);
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ Blockly.WorkspaceSvg = function(
|
||||
* @type {!Object<string, ?function(!Blockly.Workspace):!Array<!Element>>}
|
||||
* @private
|
||||
*/
|
||||
this.toolboxCategoryCallbacks_ = {};
|
||||
this.toolboxCategoryCallbacks_ = Object.create(null);
|
||||
|
||||
/**
|
||||
* Map from function names to callbacks, for deciding what to do when a button
|
||||
@@ -177,7 +177,7 @@ Blockly.WorkspaceSvg = function(
|
||||
* @type {!Object<string, ?function(!Blockly.FlyoutButton)>}
|
||||
* @private
|
||||
*/
|
||||
this.flyoutButtonCallbacks_ = {};
|
||||
this.flyoutButtonCallbacks_ = Object.create(null);
|
||||
|
||||
if (Blockly.Variables && Blockly.Variables.flyoutCategory) {
|
||||
this.registerToolboxCategoryCallback(Blockly.VARIABLE_CATEGORY_NAME,
|
||||
|
||||
@@ -887,7 +887,6 @@ WorkspaceFactoryController.prototype.clearAll = function() {
|
||||
if (!confirm(msg)) {
|
||||
return;
|
||||
}
|
||||
var hasCategories = this.model.hasElements();
|
||||
this.model.clearToolboxList();
|
||||
this.view.clearToolboxTabs();
|
||||
this.model.savePreloadXml(Blockly.utils.xml.createElement('xml'));
|
||||
@@ -1209,9 +1208,9 @@ WorkspaceFactoryController.prototype.importBlocks = function(file, format) {
|
||||
// If an imported block type is already defined, check if the user wants
|
||||
// to override the current block definition.
|
||||
if (controller.model.hasDefinedBlockTypes(blockTypes)) {
|
||||
var msg = 'An imported block uses the same name as a block '
|
||||
+ 'already in your toolbox. Are you sure you want to override the '
|
||||
+ 'currently defined block?';
|
||||
var msg = 'An imported block uses the same name as a block ' +
|
||||
'already in your toolbox. Are you sure you want to override the ' +
|
||||
'currently defined block?';
|
||||
var continueAnyway = confirm(msg);
|
||||
BlocklyDevTools.Analytics.onWarning(msg);
|
||||
if (!continueAnyway) {
|
||||
|
||||
@@ -360,7 +360,7 @@ WorkspaceFactoryModel.prototype.addCustomTag = function(category, tag) {
|
||||
* @param {!Element} xml The XML to be saved.
|
||||
*/
|
||||
WorkspaceFactoryModel.prototype.savePreloadXml = function(xml) {
|
||||
this.preloadXml = xml
|
||||
this.preloadXml = xml;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -445,8 +445,8 @@ WorkspaceFactoryModel.prototype.updateLibBlockTypes = function(blockTypes) {
|
||||
* @return {boolean} True if blockType is defined, false otherwise.
|
||||
*/
|
||||
WorkspaceFactoryModel.prototype.isDefinedBlockType = function(blockType) {
|
||||
var isStandardBlock = StandardCategories.coreBlockTypes.indexOf(blockType)
|
||||
!= -1;
|
||||
var isStandardBlock =
|
||||
StandardCategories.coreBlockTypes.indexOf(blockType) != -1;
|
||||
var isLibBlock = this.libBlockTypes.indexOf(blockType) != -1;
|
||||
var isImportedBlock = this.importedBlockTypes.indexOf(blockType) != -1;
|
||||
return (isStandardBlock || isLibBlock || isImportedBlock);
|
||||
|
||||
@@ -14,12 +14,12 @@ goog.provide('Blockly.PHP.procedures');
|
||||
|
||||
goog.require('Blockly.PHP');
|
||||
|
||||
|
||||
Blockly.PHP['procedures_defreturn'] = function(block) {
|
||||
// Define a procedure with a return value.
|
||||
// First, add a 'global' statement for every variable that is not shadowed by
|
||||
// a local parameter.
|
||||
var globals = [];
|
||||
var varName;
|
||||
var workspace = block.workspace;
|
||||
var variables = Blockly.Variables.allUsedVarModels(workspace) || [];
|
||||
for (var i = 0, variable; variable = variables[i]; i++) {
|
||||
|
||||
@@ -20,7 +20,6 @@ Blockly.Python['procedures_defreturn'] = function(block) {
|
||||
// First, add a 'global' statement for every variable that is not shadowed by
|
||||
// a local parameter.
|
||||
var globals = [];
|
||||
var varName;
|
||||
var workspace = block.workspace;
|
||||
var variables = Blockly.Variables.allUsedVarModels(workspace) || [];
|
||||
for (var i = 0, variable; variable = variables[i]; i++) {
|
||||
|
||||
@@ -398,7 +398,7 @@ return gulp.src(maybeAddClosureLibrary(['core/**/**/*.js']))
|
||||
const requires = `goog.addDependency("base.js", [], []);
|
||||
|
||||
// Load Blockly.
|
||||
goog.require('Blockly.requires')
|
||||
goog.require('Blockly.requires');
|
||||
`;
|
||||
fs.writeFileSync('blockly_uncompressed.js',
|
||||
header +
|
||||
|
||||
Reference in New Issue
Block a user