From 52884c76e4e8926dfa1c671bdfcdd5ee54920d6e Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 18 Mar 2021 16:59:43 +1100 Subject: [PATCH 1/2] fix(developer): use var not let in definitions Fixes #4716. We still support Chrome 37 on Android 5.0, which does not permit use of the `let` keyword in normal conditions. --- .../model-definitions.ts | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/developer/js/source/lexical-model-compiler/model-definitions.ts b/developer/js/source/lexical-model-compiler/model-definitions.ts index 4b5b47edf1..a4eca801c7 100644 --- a/developer/js/source/lexical-model-compiler/model-definitions.ts +++ b/developer/js/source/lexical-model-compiler/model-definitions.ts @@ -1,15 +1,15 @@ -import { defaultApplyCasing, - defaultCasedSearchTermToKey, +import { defaultApplyCasing, + defaultCasedSearchTermToKey, defaultSearchTermToKey } from "./model-defaults"; /** * Processes certain defined model behaviors in such a way that the needed closures * may be safely compiled to a JS file and loaded within the LMLayer. - * + * * This is accomplished by writing out a 'pseudoclosure' within the model's IIFE, * then used to build _actual_ closures at LMLayer load time. This 'pseudoclosure' - * will very closely match the organizational patterns of this class in order to + * will very closely match the organizational patterns of this class in order to * facilitate the maintenance of this approach. */ export class ModelDefinitions { @@ -18,10 +18,10 @@ export class ModelDefinitions { * A closure fully implementing the model's defined `applyCasing` behavior with * the function parameter preset to the version-appropriate default. * `defaults.applyCasing` is captured as part of the closure. - * + * * During compilation of some models (such as Trie-based wordlist templated models), * this closure will be directly used as part of searchTermToKey. - * + * * In compiled code, this will instead be defined in-line as an autogenerated closure * using the other properties of the pseudoclosure. */ @@ -34,7 +34,7 @@ export class ModelDefinitions { * * During compilation of some models (such as Trie-based wordlist templated models), * this closure will be directly utilized when compiling the lexicon. - * + * * In compiled code, this will instead be defined in-line as an autogenerated closure * using the other properties of the pseudoclosure. */ @@ -42,7 +42,7 @@ export class ModelDefinitions { /** * Contains embedded 'default' implementations that may be needed for - * closures in the compiled version, annotated with the current version + * closures in the compiled version, annotated with the current version * of Developer. */ private defaults: { @@ -54,7 +54,7 @@ export class ModelDefinitions { /** * Contains the model-specific definitions specified in the model's source. - * + * * These definitions may expect `defaults.applyCasing` as a parameter in * their final closures. */ @@ -95,10 +95,10 @@ export class ModelDefinitions { } else if(modelSource.languageUsesCasing == false) { this.model.searchTermToKey = defaultSearchTermToKey; } else { - // If languageUsesCasing is not defined, then we use pre-14.0 behavior, + // If languageUsesCasing is not defined, then we use pre-14.0 behavior, // which expects a lowercased default. this.model.searchTermToKey = defaultCasedSearchTermToKey; - // Needed to provide pre-14.0 default lowercasing as part of the + // Needed to provide pre-14.0 default lowercasing as part of the // search-term keying operation. this.defaults.applyCasing = defaultApplyCasing; // For compile-time use. @@ -120,18 +120,18 @@ export class ModelDefinitions { /** * Writes out a compiled JS version of the pseudoclosure, preserving all function * implementations. - * + * * This should be written to the file within the same IIFE as the model but BEFORE * the model itself, as the model will need to refer to the definitions herein. */ compileDefinitions(): string { let defn: string = ''; - defn += `let ${PSEUDOCLOSURE} = {\n` + defn += `var ${PSEUDOCLOSURE} = {\n` // ---------------------- // START - the 'defaults', which are common within the same Developer version. defn += ` defaults: {\n version: "${this.defaults.version}"`; - + // Only write out `applyCasing` if and when it is needed. if(this.defaults.applyCasing) { defn += `,\n applyCasing: ${this.defaults.applyCasing.toString()}`; @@ -153,7 +153,7 @@ export class ModelDefinitions { // END - model-specific definitions // ---------------------- - // START - compiled closures. Given those definitions, write out the + // START - compiled closures. Given those definitions, write out the // pseudoclosure-referencing closures for the needed methods. // We should be able to define these closures in-line with the object's @@ -163,7 +163,7 @@ export class ModelDefinitions { if(this.model.applyCasing) { // A major potential issue: if the user wants to call extra custom functions that they've written. // - // `applyCasing` recursion SHOULD be fine if they write `this.applyCasing() and forward all arguments + // `applyCasing` recursion SHOULD be fine if they write `this.applyCasing() and forward all arguments // appropriately, as it will be known as `applyCasing` on the runtime `this` (`model`) object. // // Similarly, as long as any helper functions are similarly compiled and stored as part of `model`, From 2c383cabe4af0b781264cb582ceec4ed93abdd1e Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 18 Mar 2021 17:51:59 +1100 Subject: [PATCH 2/2] fix(developer): downgrade additional let and arrow functions --- .../lexical-model-compiler/model-defaults.ts | 16 +++++----- developer/js/tests/test-model-definitions.ts | 32 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/developer/js/source/lexical-model-compiler/model-defaults.ts b/developer/js/source/lexical-model-compiler/model-defaults.ts index 6880969b43..cf51575ccc 100644 --- a/developer/js/source/lexical-model-compiler/model-defaults.ts +++ b/developer/js/source/lexical-model-compiler/model-defaults.ts @@ -49,22 +49,22 @@ export function defaultSearchTermToKey(wordform: string): string { */ export function defaultCasedSearchTermToKey(wordform: string, applyCasing: CasingFunction): string { // While this is a bit WET, as the basic `defaultSearchTermToKey` exists and performs some of - // the same functions, repetition is the easiest way to allow the function to be safely compiled + // the same functions, repetition is the easiest way to allow the function to be safely compiled // with ease by use of `.toString()`. return Array.from(wordform .normalize('NFKD') // Remove any combining diacritics (if input is in NFKD) .replace(/[\u0300-\u036F]/g, '') ) // end of `Array.from` - .map(c => applyCasing('lower', c)) + .map(function(c) { return applyCasing('lower', c)}) .join(''); } /** * Specifies default casing behavior for lexical models when `languageUsesCasing` is * set to true. - * @param casing One of 'lower' (lowercased), 'upper' (uppercased), or 'initial'. - * + * @param casing One of 'lower' (lowercased), 'upper' (uppercased), or 'initial'. + * * 'initial' is designed to cover cases like sentence-initial & proper noun capitalization in English. * This may be overwritten as appropriate in model-specific implementations. * @param text The text to be modified. @@ -76,15 +76,15 @@ export function defaultApplyCasing(casing: CasingForm, text: string): string { case 'upper': return text.toUpperCase(); case 'initial': - let headCode = text.charCodeAt(0); + var headCode = text.charCodeAt(0); // The length of the first code unit, as measured in code points. - let headUnitLength = 1; + var headUnitLength = 1; - // Is the first character a high surrogate, indicating possible use of UTF-16 + // Is the first character a high surrogate, indicating possible use of UTF-16 // surrogate pairs? Also, is the string long enough for there to BE a pair? if(text.length > 1 && headCode >= 0xD800 && headCode <= 0xDBFF) { // It's possible, so now we check for low surrogates. - let lowSurrogateCode = text.charCodeAt(1); + var lowSurrogateCode = text.charCodeAt(1); if(lowSurrogateCode >= 0xDC00 && lowSurrogateCode <= 0xDFFF) { // We have a surrogate pair; this pair is the 'first' character. diff --git a/developer/js/tests/test-model-definitions.ts b/developer/js/tests/test-model-definitions.ts index bacd236762..67b49859b4 100644 --- a/developer/js/tests/test-model-definitions.ts +++ b/developer/js/tests/test-model-definitions.ts @@ -19,7 +19,7 @@ describe('Model definition pseudoclosures', function () { // Note: not written the Turkish way. Turns out 'İ'.toLowerCase() decomposes the result, // which would have made for a fairly yucky test. ['Istanbul', 'istanbul', 'istanbul'], - + // The DEFAULT function is NOT responsible for understanding the Turkish // case regarding the lowercasing of: // 'I' U+0048 LATIN CAPITAL LETTER I to 'ı' U+0131 LATIN SMALL LETTER DOTLESS I @@ -29,14 +29,14 @@ describe('Model definition pseudoclosures', function () { // full-width romaji has corresponding lowercased versions: ['AESTHETIC', 'aesthetic', 'aesthetic'], - + // "skýlos" is Greek for dog 🇬🇷🐶 // starts with an 's' and ends with an 's' // which are DIFFERENT CHARACTERS in lowercased Greek! ['σκύλος', 'σκύλος', 'σκυλος'], - ['ΣΚΥΛΟΣ', 'σκυλος', 'σκυλοσ'], // the keyed version after lowercasing doesn't know how + ['ΣΚΥΛΟΣ', 'σκυλος', 'σκυλοσ'], // the keyed version after lowercasing doesn't know how // to make the distinction. Both 'Σ's have the same char-code. - + // Uncased syntax and numbers should pass through unscathed: ['1234.?!', '1234.?!', '1234.?!'] ]; @@ -67,19 +67,19 @@ describe('Model definition pseudoclosures', function () { // Note: not written the Turkish way. Turns out 'İ'.toLowerCase() decomposes the result, // which would have made for a fairly yucky test. ['Istanbul', 'Istanbul'], - + ['DİYARBAKIR', 'DIYARBAKIR'], // full-width romaji has corresponding capitalized versions: ['AESTHETIC', 'AESTHETIC'], - + // "skýlos" is Greek for dog 🇬🇷🐶 // starts with an 's' and ends with an 's' // which are DIFFERENT CHARACTERS in lowercased Greek! ['σκύλος', 'σκυλος'], - ['ΣΚΥΛΟΣ', 'ΣΚΥΛΟΣ'], // the keyed version after lowercasing doesn't know how + ['ΣΚΥΛΟΣ', 'ΣΚΥΛΟΣ'], // the keyed version after lowercasing doesn't know how // to make the distinction. Both 'Σ's have the same char-code. - + // Uncased syntax and numbers should pass through unscathed: ['1234.?!', '1234.?!'] ]; @@ -105,19 +105,19 @@ describe('Model definition pseudoclosures', function () { // Note: not written the Turkish way. Turns out 'İ'.toLowerCase() decomposes the result, // which would have made for a fairly yucky test. ['Istanbul', 'istanbul'], - + ['DİYARBAKIR', 'diyarbakir'], // full-width romaji has corresponding capitalized versions: ['AESTHETIC', 'aesthetic'], - + // "skýlos" is Greek for dog 🇬🇷🐶 // starts with an 's' and ends with an 's' // which are DIFFERENT CHARACTERS in lowercased Greek! ['σκύλος', 'σκυλος'], - ['ΣΚΥΛΟΣ', 'σκυλοσ'], // the keyed version after lowercasing doesn't know how + ['ΣΚΥΛΟΣ', 'σκυλοσ'], // the keyed version after lowercasing doesn't know how // to make the distinction. Both 'Σ's have the same char-code. - + // Uncased syntax and numbers should pass through unscathed: ['1234.?!', '1234.?!'] ]; @@ -143,7 +143,7 @@ describe('Model definition pseudoclosures', function () { .replace(/ı/g, 'I') .replace(/i/g, 'İ')); case 'initial': - return turkishCasing('upper', text.charAt(0), defaultApplyCasing) + text.substr(1); + return turkishCasing('upper', text.charAt(0), defaultApplyCasing) + text.substr(1); default: return text; } @@ -156,7 +156,7 @@ describe('Model definition pseudoclosures', function () { return Array.from(wordform .normalize('NFC') // Mostly to avoid decomposing 'İ' ) // end of `Array.from` - .map(c => applyCasing('lower', c)) // Will use custom `applyCasing` definition! + .map(function(c) { return applyCasing('lower', c)}) // Will use custom `applyCasing` definition! .join(''); }, sources: [], @@ -167,14 +167,14 @@ describe('Model definition pseudoclosures', function () { const testCases: [string, string, string][] = [ ['İstanbul', 'istanbul', 'istanbul'], - + // The DEFAULT function is NOT responsible for understanding the Turkish // case regarding the lowercasing of: // 'I' U+0048 LATIN CAPITAL LETTER I to 'ı' U+0131 LATIN SMALL LETTER DOTLESS I // For Turkic languages, the recommendation is to make a // custom applyCasing function: ['DİYARBAKIR', 'diyarbakır', 'diyarbakır'], - + // Uncased syntax and numbers should pass through unscathed: ['1234.?!', '1234.?!', '1234.?!'] ];