From 63ca83b545d9f00ed8a7e0be6ff8c54dc909e1a7 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Wed, 27 Apr 2022 15:25:07 -0700 Subject: [PATCH] chore: Make startsWith faster (#6118) by using built-in function (polyfill will handle IE). --- core/touch.js | 11 ++++------- core/utils/parsing.js | 6 ++---- core/utils/string.js | 11 ++++++++--- scripts/gulpfiles/chunks.json | 4 ++-- tests/deps.js | 4 ++-- tests/mocha/utils_test.js | 7 ------- typings/blockly.d.ts | 11 +---------- 7 files changed, 19 insertions(+), 35 deletions(-) diff --git a/core/touch.js b/core/touch.js index 4d85c42c7..aa3b989e4 100644 --- a/core/touch.js +++ b/core/touch.js @@ -15,7 +15,6 @@ */ goog.module('Blockly.Touch'); -const utilsString = goog.require('Blockly.utils.string'); /* eslint-disable-next-line no-unused-vars */ const {Gesture} = goog.requireType('Blockly.Gesture'); const {globalThis} = goog.require('Blockly.utils.global'); @@ -246,7 +245,7 @@ exports.checkTouchIdentifier = checkTouchIdentifier; * @alias Blockly.Touch.setClientFromTouch */ const setClientFromTouch = function(e) { - if (utilsString.startsWith(e.type, 'touch') && e.changedTouches) { + if (e.type.startsWith('touch') && e.changedTouches) { // Map the touch event's properties to the event. const touchPoint = e.changedTouches[0]; e.clientX = touchPoint.clientX; @@ -263,9 +262,8 @@ exports.setClientFromTouch = setClientFromTouch; * @alias Blockly.Touch.isMouseOrTouchEvent */ const isMouseOrTouchEvent = function(e) { - return utilsString.startsWith(e.type, 'touch') || - utilsString.startsWith(e.type, 'mouse') || - utilsString.startsWith(e.type, 'pointer'); + return e.type.startsWith('touch') || e.type.startsWith('mouse') || + e.type.startsWith('pointer'); }; exports.isMouseOrTouchEvent = isMouseOrTouchEvent; @@ -276,8 +274,7 @@ exports.isMouseOrTouchEvent = isMouseOrTouchEvent; * @alias Blockly.Touch.isTouchEvent */ const isTouchEvent = function(e) { - return utilsString.startsWith(e.type, 'touch') || - utilsString.startsWith(e.type, 'pointer'); + return e.type.startsWith('touch') || e.type.startsWith('pointer'); }; exports.isTouchEvent = isTouchEvent; diff --git a/core/utils/parsing.js b/core/utils/parsing.js index b8eb9bedf..f2c6eb82e 100644 --- a/core/utils/parsing.js +++ b/core/utils/parsing.js @@ -15,7 +15,6 @@ goog.module('Blockly.utils.parsing'); const colourUtils = goog.require('Blockly.utils.colour'); -const stringUtils = goog.require('Blockly.utils.string'); const {Msg} = goog.require('Blockly.Msg'); @@ -97,9 +96,8 @@ const tokenizeInterpolationInternal = function( // BKY_ is the prefix used to namespace the strings used in Blockly // core files and the predefined blocks in ../blocks/. // These strings are defined in ../msgs/ files. - const bklyKey = stringUtils.startsWith(keyUpper, 'BKY_') ? - keyUpper.substring(4) : - null; + const bklyKey = + keyUpper.startsWith('BKY_') ? keyUpper.substring(4) : null; if (bklyKey && bklyKey in Msg) { const rawValue = Msg[bklyKey]; if (typeof rawValue === 'string') { diff --git a/core/utils/string.js b/core/utils/string.js index 463e1c1f8..2afc21b55 100644 --- a/core/utils/string.js +++ b/core/utils/string.js @@ -19,17 +19,22 @@ */ goog.module('Blockly.utils.string'); +const deprecation = goog.require('Blockly.utils.deprecation'); + /** - * Fast prefix-checker. - * Copied from Closure's goog.string.startsWith. + * Obsolete prefix-checker. * @param {string} str The string to check. * @param {string} prefix A string to look for at the start of `str`. * @return {boolean} True if `str` begins with `prefix`. * @alias Blockly.utils.string.startsWith + * @deprecated April 2022. Use built-in string.startsWith. */ const startsWith = function(str, prefix) { - return str.lastIndexOf(prefix, 0) === 0; + deprecation.warn( + 'Blockly.utils.string.startsWith()', 'April 2022', 'April 2023', + 'Use built-in string.startsWith'); + return str.startsWith(prefix); }; exports.startsWith = startsWith; diff --git a/scripts/gulpfiles/chunks.json b/scripts/gulpfiles/chunks.json index fce78801f..503da3e26 100644 --- a/scripts/gulpfiles/chunks.json +++ b/scripts/gulpfiles/chunks.json @@ -131,9 +131,9 @@ "./core/renderers/zelos/measurables/row_elements.js", "./core/renderers/zelos/marker_svg.js", "./core/renderers/zelos/measurables/inputs.js", - "./core/renderers/zelos/path_object.js", "./core/renderers/zelos/drawer.js", "./core/renderers/zelos/renderer.js", + "./core/renderers/zelos/path_object.js", "./core/field_textinput.js", "./core/field_image.js", "./core/renderers/zelos/constants.js", @@ -229,7 +229,6 @@ "./core/events/events_bubble_open.js", "./core/procedures.js", "./core/workspace_svg.js", - "./core/utils/rect.js", "./core/utils/deprecation.js", "./core/utils/svg_math.js", "./core/bubble_dragger.js", @@ -242,6 +241,7 @@ "./core/tooltip.js", "./core/block_svg.js", "./core/utils/size.js", + "./core/utils/rect.js", "./core/utils/coordinate.js", "./core/utils/style.js", "./core/dropdowndiv.js", diff --git a/tests/deps.js b/tests/deps.js index a0e041a7b..ef58fe214 100644 --- a/tests/deps.js +++ b/tests/deps.js @@ -224,7 +224,7 @@ goog.addDependency('../../core/toolbox/separator.js', ['Blockly.ToolboxSeparator goog.addDependency('../../core/toolbox/toolbox.js', ['Blockly.Toolbox'], ['Blockly.BlockSvg', 'Blockly.CollapsibleToolboxCategory', 'Blockly.ComponentManager', 'Blockly.Css', 'Blockly.DeleteArea', 'Blockly.Events.ToolboxItemSelect', 'Blockly.Events.utils', 'Blockly.IAutoHideable', 'Blockly.IKeyboardAccessible', 'Blockly.IStyleable', 'Blockly.IToolbox', 'Blockly.Options', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.common', 'Blockly.registry', 'Blockly.utils.KeyCodes', 'Blockly.utils.Rect', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/toolbox/toolbox_item.js', ['Blockly.ToolboxItem'], ['Blockly.IToolboxItem', 'Blockly.utils.idGenerator'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/tooltip.js', ['Blockly.Tooltip'], ['Blockly.browserEvents', 'Blockly.common', 'Blockly.utils.deprecation', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'}); -goog.addDependency('../../core/touch.js', ['Blockly.Touch'], ['Blockly.utils.global', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../core/touch.js', ['Blockly.Touch'], ['Blockly.utils.global'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/touch_gesture.js', ['Blockly.TouchGesture'], ['Blockly.Gesture', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.utils.Coordinate'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.ComponentManager', 'Blockly.DeleteArea', 'Blockly.Events.TrashcanOpen', 'Blockly.Events.utils', 'Blockly.IAutoHideable', 'Blockly.IPositionable', 'Blockly.Options', 'Blockly.browserEvents', 'Blockly.registry', 'Blockly.sprite', 'Blockly.uiPosition', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/utils.js', ['Blockly.utils'], ['Blockly.Extensions', 'Blockly.browserEvents', 'Blockly.common', 'Blockly.utils.Coordinate', 'Blockly.utils.KeyCodes', 'Blockly.utils.Metrics', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.aria', 'Blockly.utils.array', 'Blockly.utils.colour', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.global', 'Blockly.utils.idGenerator', 'Blockly.utils.math', 'Blockly.utils.object', 'Blockly.utils.parsing', 'Blockly.utils.string', 'Blockly.utils.style', 'Blockly.utils.svgMath', 'Blockly.utils.svgPaths', 'Blockly.utils.toolbox', 'Blockly.utils.userAgent', 'Blockly.utils.xml'], {'lang': 'es6', 'module': 'goog'}); @@ -240,7 +240,7 @@ goog.addDependency('../../core/utils/keycodes.js', ['Blockly.utils.KeyCodes'], [ goog.addDependency('../../core/utils/math.js', ['Blockly.utils.math'], [], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/utils/metrics.js', ['Blockly.utils.Metrics'], [], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/utils/object.js', ['Blockly.utils.object'], [], {'lang': 'es6', 'module': 'goog'}); -goog.addDependency('../../core/utils/parsing.js', ['Blockly.utils.parsing'], ['Blockly.Msg', 'Blockly.utils.colour', 'Blockly.utils.string'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../core/utils/parsing.js', ['Blockly.utils.parsing'], ['Blockly.Msg', 'Blockly.utils.colour'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/utils/rect.js', ['Blockly.utils.Rect'], [], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/utils/sentinel.js', ['Blockly.utils.Sentinel'], [], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/utils/size.js', ['Blockly.utils.Size'], [], {'lang': 'es6', 'module': 'goog'}); diff --git a/tests/mocha/utils_test.js b/tests/mocha/utils_test.js index 57ce83f10..b21d45465 100644 --- a/tests/mocha/utils_test.js +++ b/tests/mocha/utils_test.js @@ -364,13 +364,6 @@ suite('Utils', function() { }); suite('String', function() { - test('starts with', function() { - chai.assert.isFalse(Blockly.utils.string.startsWith('123', '2'), 'Does not start with'); - chai.assert.isTrue(Blockly.utils.string.startsWith('123', '12'), 'Start with'); - chai.assert.isTrue(Blockly.utils.string.startsWith('123', ''), 'Start with empty string 1'); - chai.assert.isTrue(Blockly.utils.string.startsWith('', ''), 'Start with empty string 12'); - }); - test('shortest string length', function() { let len = Blockly.utils.string.shortestStringLength('one,two,three,four,five'.split(',')); chai.assert.equal(len, 3, 'Length of "one"'); diff --git a/typings/blockly.d.ts b/typings/blockly.d.ts index b2fe86e59..c13b1f098 100644 --- a/typings/blockly.d.ts +++ b/typings/blockly.d.ts @@ -100,15 +100,6 @@ declare module "core/utils/colour" { export function hueToHex(hue: number): string; } declare module "core/utils/string" { - /** - * Fast prefix-checker. - * Copied from Closure's goog.string.startsWith. - * @param {string} str The string to check. - * @param {string} prefix A string to look for at the start of `str`. - * @return {boolean} True if `str` begins with `prefix`. - * @alias Blockly.utils.string.startsWith - */ - export function startsWith(str: string, prefix: string): boolean; /** * Given an array of strings, return the length of the shortest one. * @param {!Array} array Array of strings. @@ -8041,7 +8032,7 @@ declare module "core/renderers/common/constants" { * colourTertiary:(string|undefined), * hat:(string|undefined) * }} blockStyle A full or partial block style object. - + * @return {!Theme.BlockStyle} A full block style object, with all * required properties populated. * @protected