Skip to content

Commit

Permalink
Migrate core/utils/string.js to goog.module syntax (#5059)
Browse files Browse the repository at this point in the history
* Migrate core/utils/string.js to ES6 const/let

* Migrate core/utils/string.js to goog.module

* clang-format core/utils/string.js

* Migrate core/utils/string.js to current exports convention

* Convert two remaining vars to lets in core/utils/string.js
  • Loading branch information
gonfunko authored Aug 12, 2021
1 parent c86c8f8 commit ee3f4d2
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 66 deletions.
135 changes: 70 additions & 65 deletions core/utils/string.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
* @name Blockly.utils.string
* @namespace
*/
goog.provide('Blockly.utils.string');
goog.module('Blockly.utils.string');
goog.module.declareLegacyNamespace();


/**
Expand All @@ -26,23 +27,27 @@ goog.provide('Blockly.utils.string');
* @param {string} prefix A string to look for at the start of `str`.
* @return {boolean} True if `str` begins with `prefix`.
*/
Blockly.utils.string.startsWith = function(str, prefix) {
const startsWith = function(str, prefix) {
return str.lastIndexOf(prefix, 0) == 0;
};
exports.startsWith = startsWith;

/**
* Given an array of strings, return the length of the shortest one.
* @param {!Array<string>} array Array of strings.
* @return {number} Length of shortest string.
*/
Blockly.utils.string.shortestStringLength = function(array) {
const shortestStringLength = function(array) {
if (!array.length) {
return 0;
}
return array.reduce(function(a, b) {
return a.length < b.length ? a : b;
}).length;
return array
.reduce(function(a, b) {
return a.length < b.length ? a : b;
})
.length;
};
exports.shortestStringLength = shortestStringLength;

/**
* Given an array of strings, return the length of the common prefix.
Expand All @@ -51,17 +56,18 @@ Blockly.utils.string.shortestStringLength = function(array) {
* @param {number=} opt_shortest Length of shortest string.
* @return {number} Length of common prefix.
*/
Blockly.utils.string.commonWordPrefix = function(array, opt_shortest) {
const commonWordPrefix = function(array, opt_shortest) {
if (!array.length) {
return 0;
} else if (array.length == 1) {
return array[0].length;
}
var wordPrefix = 0;
var max = opt_shortest || Blockly.utils.string.shortestStringLength(array);
for (var len = 0; len < max; len++) {
var letter = array[0][len];
for (var i = 1; i < array.length; i++) {
let wordPrefix = 0;
const max = opt_shortest || shortestStringLength(array);
let len;
for (len = 0; len < max; len++) {
const letter = array[0][len];
for (let i = 1; i < array.length; i++) {
if (letter != array[i][len]) {
return wordPrefix;
}
Expand All @@ -70,14 +76,15 @@ Blockly.utils.string.commonWordPrefix = function(array, opt_shortest) {
wordPrefix = len + 1;
}
}
for (var i = 1; i < array.length; i++) {
var letter = array[i][len];
for (let i = 1; i < array.length; i++) {
const letter = array[i][len];
if (letter && letter != ' ') {
return wordPrefix;
}
}
return max;
};
exports.commonWordPrefix = commonWordPrefix;

/**
* Given an array of strings, return the length of the common suffix.
Expand All @@ -86,17 +93,18 @@ Blockly.utils.string.commonWordPrefix = function(array, opt_shortest) {
* @param {number=} opt_shortest Length of shortest string.
* @return {number} Length of common suffix.
*/
Blockly.utils.string.commonWordSuffix = function(array, opt_shortest) {
const commonWordSuffix = function(array, opt_shortest) {
if (!array.length) {
return 0;
} else if (array.length == 1) {
return array[0].length;
}
var wordPrefix = 0;
var max = opt_shortest || Blockly.utils.string.shortestStringLength(array);
for (var len = 0; len < max; len++) {
var letter = array[0].substr(-len - 1, 1);
for (var i = 1; i < array.length; i++) {
let wordPrefix = 0;
const max = opt_shortest || shortestStringLength(array);
let len;
for (len = 0; len < max; len++) {
const letter = array[0].substr(-len - 1, 1);
for (let i = 1; i < array.length; i++) {
if (letter != array[i].substr(-len - 1, 1)) {
return wordPrefix;
}
Expand All @@ -105,74 +113,75 @@ Blockly.utils.string.commonWordSuffix = function(array, opt_shortest) {
wordPrefix = len + 1;
}
}
for (var i = 1; i < array.length; i++) {
var letter = array[i].charAt(array[i].length - len - 1);
for (let i = 1; i < array.length; i++) {
const letter = array[i].charAt(array[i].length - len - 1);
if (letter && letter != ' ') {
return wordPrefix;
}
}
return max;
};
exports.commonWordSuffix = commonWordSuffix;

/**
* Wrap text to the specified width.
* @param {string} text Text to wrap.
* @param {number} limit Width to wrap each line.
* @return {string} Wrapped text.
*/
Blockly.utils.string.wrap = function(text, limit) {
var lines = text.split('\n');
for (var i = 0; i < lines.length; i++) {
lines[i] = Blockly.utils.string.wrapLine_(lines[i], limit);
const wrap = function(text, limit) {
const lines = text.split('\n');
for (let i = 0; i < lines.length; i++) {
lines[i] = wrapLine(lines[i], limit);
}
return lines.join('\n');
};
exports.wrap = wrap;

/**
* Wrap single line of text to the specified width.
* @param {string} text Text to wrap.
* @param {number} limit Width to wrap each line.
* @return {string} Wrapped text.
* @private
*/
Blockly.utils.string.wrapLine_ = function(text, limit) {
const wrapLine = function(text, limit) {
if (text.length <= limit) {
// Short text, no need to wrap.
return text;
}
// Split the text into words.
var words = text.trim().split(/\s+/);
const words = text.trim().split(/\s+/);
// Set limit to be the length of the largest word.
for (var i = 0; i < words.length; i++) {
for (let i = 0; i < words.length; i++) {
if (words[i].length > limit) {
limit = words[i].length;
}
}

var lastScore;
var score = -Infinity;
var lastText;
var lineCount = 1;
let lastScore;
let score = -Infinity;
let lastText;
let lineCount = 1;
do {
lastScore = score;
lastText = text;
// Create a list of booleans representing if a space (false) or
// a break (true) appears after each word.
var wordBreaks = [];
let wordBreaks = [];
// Seed the list with evenly spaced linebreaks.
var steps = words.length / lineCount;
var insertedBreaks = 1;
for (var i = 0; i < words.length - 1; i++) {
const steps = words.length / lineCount;
let insertedBreaks = 1;
for (let i = 0; i < words.length - 1; i++) {
if (insertedBreaks < (i + 1.5) / steps) {
insertedBreaks++;
wordBreaks[i] = true;
} else {
wordBreaks[i] = false;
}
}
wordBreaks = Blockly.utils.string.wrapMutate_(words, wordBreaks, limit);
score = Blockly.utils.string.wrapScore_(words, wordBreaks, limit);
text = Blockly.utils.string.wrapToText_(words, wordBreaks);
wordBreaks = wrapMutate(words, wordBreaks, limit);
score = wrapScore(words, wordBreaks, limit);
text = wrapToText(words, wordBreaks);
lineCount++;
} while (score > lastScore);
return lastText;
Expand All @@ -184,14 +193,13 @@ Blockly.utils.string.wrapLine_ = function(text, limit) {
* @param {!Array<boolean>} wordBreaks Array of line breaks.
* @param {number} limit Width to wrap each line.
* @return {number} Larger the better.
* @private
*/
Blockly.utils.string.wrapScore_ = function(words, wordBreaks, limit) {
const wrapScore = function(words, wordBreaks, limit) {
// If this function becomes a performance liability, add caching.
// Compute the length of each line.
var lineLengths = [0];
var linePunctuation = [];
for (var i = 0; i < words.length; i++) {
const lineLengths = [0];
const linePunctuation = [];
for (let i = 0; i < words.length; i++) {
lineLengths[lineLengths.length - 1] += words[i].length;
if (wordBreaks[i] === true) {
lineLengths.push(0);
Expand All @@ -200,10 +208,10 @@ Blockly.utils.string.wrapScore_ = function(words, wordBreaks, limit) {
lineLengths[lineLengths.length - 1]++;
}
}
var maxLength = Math.max.apply(Math, lineLengths);
const maxLength = Math.max.apply(Math, lineLengths);

var score = 0;
for (var i = 0; i < lineLengths.length; i++) {
let score = 0;
for (let i = 0; i < lineLengths.length; i++) {
// Optimize for width.
// -2 points per char over limit (scaled to the power of 1.5).
score -= Math.pow(Math.abs(limit - lineLengths[i]), 1.5) * 2;
Expand All @@ -222,8 +230,9 @@ Blockly.utils.string.wrapScore_ = function(words, wordBreaks, limit) {
// previous line. For example, this looks wrong:
// aaa bbb
// ccc ddd eee
if (lineLengths.length > 1 && lineLengths[lineLengths.length - 1] <=
lineLengths[lineLengths.length - 2]) {
if (lineLengths.length > 1 &&
lineLengths[lineLengths.length - 1] <=
lineLengths[lineLengths.length - 2]) {
score += 0.5;
}
return score;
Expand All @@ -236,29 +245,27 @@ Blockly.utils.string.wrapScore_ = function(words, wordBreaks, limit) {
* @param {!Array<boolean>} wordBreaks Array of line breaks.
* @param {number} limit Width to wrap each line.
* @return {!Array<boolean>} New array of optimal line breaks.
* @private
*/
Blockly.utils.string.wrapMutate_ = function(words, wordBreaks, limit) {
var bestScore = Blockly.utils.string.wrapScore_(words, wordBreaks, limit);
var bestBreaks;
const wrapMutate = function(words, wordBreaks, limit) {
let bestScore = wrapScore(words, wordBreaks, limit);
let bestBreaks;
// Try shifting every line break forward or backward.
for (var i = 0; i < wordBreaks.length - 1; i++) {
for (let i = 0; i < wordBreaks.length - 1; i++) {
if (wordBreaks[i] == wordBreaks[i + 1]) {
continue;
}
var mutatedWordBreaks = [].concat(wordBreaks);
const mutatedWordBreaks = [].concat(wordBreaks);
mutatedWordBreaks[i] = !mutatedWordBreaks[i];
mutatedWordBreaks[i + 1] = !mutatedWordBreaks[i + 1];
var mutatedScore =
Blockly.utils.string.wrapScore_(words, mutatedWordBreaks, limit);
const mutatedScore = wrapScore(words, mutatedWordBreaks, limit);
if (mutatedScore > bestScore) {
bestScore = mutatedScore;
bestBreaks = mutatedWordBreaks;
}
}
if (bestBreaks) {
// Found an improvement. See if it may be improved further.
return Blockly.utils.string.wrapMutate_(words, bestBreaks, limit);
return wrapMutate(words, bestBreaks, limit);
}
// No improvements found. Done.
return wordBreaks;
Expand All @@ -269,16 +276,14 @@ Blockly.utils.string.wrapMutate_ = function(words, wordBreaks, limit) {
* @param {!Array<string>} words Array of each word.
* @param {!Array<boolean>} wordBreaks Array of line breaks.
* @return {string} Plain text.
* @private
*/
Blockly.utils.string.wrapToText_ = function(words, wordBreaks) {
var text = [];
for (var i = 0; i < words.length; i++) {
const wrapToText = function(words, wordBreaks) {
const text = [];
for (let i = 0; i < words.length; i++) {
text.push(words[i]);
if (wordBreaks[i] !== undefined) {
text.push(wordBreaks[i] ? '\n' : ' ');
}
}
return text.join('');
};

2 changes: 1 addition & 1 deletion tests/deps.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit ee3f4d2

Please sign in to comment.