mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-10 09:37:42 +00:00
chore(web): further PR cleanup
This commit is contained in:
parent
f36aba7bad
commit
aefef2181d
5 changed files with 55 additions and 23 deletions
|
|
@ -1,7 +1,7 @@
|
|||
///<reference types="@keymanapp/models-types" />
|
||||
|
||||
import { extendString } from "@keymanapp/web-utils";
|
||||
import { searchStringDivergence } from "./stringDivergence.js";
|
||||
import { findCommonSubstringEndIndex } from "./stringDivergence.js";
|
||||
|
||||
extendString();
|
||||
|
||||
|
|
@ -124,14 +124,14 @@ export default abstract class OutputTarget {
|
|||
const toLeft = this.getTextBeforeCaret();
|
||||
const fromLeft = original.getTextBeforeCaret();
|
||||
|
||||
const leftDivergenceIndex = searchStringDivergence(fromLeft, toLeft, false);
|
||||
const leftDivergenceIndex = findCommonSubstringEndIndex(fromLeft, toLeft, false);
|
||||
const deletedLeft = fromLeft.substring(leftDivergenceIndex)._kmwLength();
|
||||
// No need for our specialized variant here.
|
||||
const insertedText = toLeft.substring(leftDivergenceIndex);
|
||||
|
||||
const toRight = this.getTextAfterCaret();
|
||||
const fromRight = original.getTextAfterCaret();
|
||||
const rightDivergenceIndex = searchStringDivergence(fromRight, toRight, true);
|
||||
const rightDivergenceIndex = findCommonSubstringEndIndex(fromRight, toRight, true);
|
||||
|
||||
// Right insertions aren't supported, but right deletions will matter in some scenarios.
|
||||
// In particular, once we allow right-deletion for pred-text suggestions applied with the
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
// Future TODO: import from @keymanapp/common-types... once we no longer need to support ES5.
|
||||
import { Uni_IsSurrogate1, Uni_IsSurrogate2 } from '@keymanapp/web-utils';
|
||||
|
||||
/**
|
||||
* Returns the index for the code point divergence point in code unit coordinates.
|
||||
* Returns the index for the code point divergence point between two strings, as measured in code
|
||||
* unit coordinates.
|
||||
* @param str1
|
||||
* @param str2
|
||||
* @param commonSuffix If false, asserts a common prefix to the strings. If true, asserts a common suffix.
|
||||
* @returns The code unit index within `str1` for the start of the code point not common to both.
|
||||
*/
|
||||
export function searchStringDivergence(str1: string, str2: string, commonSuffix: boolean): number {
|
||||
export function findCommonSubstringEndIndex(str1: string, str2: string, commonSuffix: boolean): number {
|
||||
/**
|
||||
* The maximum number of iterations to consider; exceeding this would go past a string boundary.
|
||||
*/
|
||||
|
|
@ -67,16 +71,15 @@ export function searchStringDivergence(str1: string, str2: string, commonSuffix:
|
|||
const divergentChar1 = str1.charCodeAt(index);
|
||||
const divergentChar2 = str2.charCodeAt(index + offset);
|
||||
|
||||
const isHigh = (charCode: number) => charCode >= 0xD800 && charCode <= 0xDBFF;
|
||||
const isLow = (charCode: number) => charCode >= 0xDC00 && charCode <= 0xDFFF;
|
||||
const commonChecker = commonSuffix ? isLow : isHigh;
|
||||
const divergentChecker = commonSuffix ? isHigh : isLow;
|
||||
const commonSurrogateChecker = commonSuffix ? Uni_IsSurrogate2 : Uni_IsSurrogate1;
|
||||
const divergentSurrogateChecker = commonSuffix ? Uni_IsSurrogate1 : Uni_IsSurrogate2;
|
||||
|
||||
// If the last common char qualifies as a direction-appropriate SMP surrogate...
|
||||
if(commonChecker(commonPotentialSurrogate)) {
|
||||
// If the last common character if of the direction-appropriate surrogate type (for
|
||||
// comprising a potential split surrogate pair representing a non-BMP char)...
|
||||
if(commonSurrogateChecker(commonPotentialSurrogate)) {
|
||||
// And one of the two divergent chars is a qualifying match - a surrogate
|
||||
// of the opposite type...
|
||||
if(divergentChecker(divergentChar1) || divergentChecker(divergentChar2)) {
|
||||
if(divergentSurrogateChecker(divergentChar1) || divergentSurrogateChecker(divergentChar2)) {
|
||||
// Our current index would split a surrogate pair; decrement the index to
|
||||
// preserve the pair.
|
||||
return index - inc;
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ extendString(); // Ensure KMW's string-extension functionality is available.
|
|||
|
||||
String.kmwEnableSupplementaryPlane(false);
|
||||
|
||||
// A unicode-coding like alias for use in constructing SMP strings.
|
||||
// A unicode-coding like alias for use in constructing non-BMP strings.
|
||||
const u = String.fromCodePoint;
|
||||
|
||||
/**
|
||||
* Returns the "Mathematical Sans-Serif Small" SMP encoding for
|
||||
* Returns the "Mathematical Sans-Serif Small" non-BMP encoding for
|
||||
* a passed-in lowercase char between 'a' and 'z', inclusive.
|
||||
* @param {*} char
|
||||
* @returns
|
||||
|
|
@ -39,7 +39,7 @@ describe("String divergence calculations", function() {
|
|||
assert.equal(result2, 0);
|
||||
});
|
||||
|
||||
it("SMP text", () => {
|
||||
it("non-BMP text", () => {
|
||||
const smp_ify = (str) => str.split('').map(ss).join('');
|
||||
|
||||
const result1 = searchStringDivergence(
|
||||
|
|
@ -48,7 +48,7 @@ describe("String divergence calculations", function() {
|
|||
false
|
||||
);
|
||||
|
||||
// 2 per SMP char; is in code-unit... units.
|
||||
// 2 per non-BMP char; is in code-unit... units.
|
||||
// Will avoid splitting code points, though.
|
||||
assert.equal(result1, 8);
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ describe("String divergence calculations", function() {
|
|||
assert.equal(result2, 8);
|
||||
});
|
||||
|
||||
it("SMP edge cases", () => {
|
||||
it("non-BMP edge cases", () => {
|
||||
const smp_ify = (str) => str.split('').map(ss).join('');
|
||||
|
||||
const result1 = searchStringDivergence(
|
||||
|
|
@ -106,7 +106,7 @@ describe("String divergence calculations", function() {
|
|||
assert.equal(result2, "post-caret text".length-1);
|
||||
})
|
||||
|
||||
it("SMP text", () => {
|
||||
it("non-BMP text", () => {
|
||||
const smp_ify = (str) => str.split('').map(ss).join('');
|
||||
|
||||
// att|endance
|
||||
|
|
@ -117,7 +117,7 @@ describe("String divergence calculations", function() {
|
|||
true
|
||||
);
|
||||
|
||||
// 2 per SMP char; is in code-unit... units.
|
||||
// 2 per non-BMP char; is in code-unit... units.
|
||||
// Will avoid splitting code points; is odd b/c we get the index of the LAST char of the pair.
|
||||
assert.equal(result1, 5);
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ describe("String divergence calculations", function() {
|
|||
|
||||
});
|
||||
|
||||
it("SMP edge cases", () => {
|
||||
it("non-BMP edge cases", () => {
|
||||
const smp_ify = (str) => str.split('').map(ss).join('');
|
||||
|
||||
// If the two are equal...
|
||||
|
|
@ -155,7 +155,7 @@ describe("String divergence calculations", function() {
|
|||
});
|
||||
|
||||
describe("Transcriptions and Transforms", function() {
|
||||
// Built in-line via function. Looks functionally equivalent to "apple", but with SMP characters.
|
||||
// Built in-line via function. Looks functionally equivalent to "apple", but with non-BMP characters.
|
||||
let smpApple = u(0x1d5ba)+u(0x1d5c9)+u(0x1d5c9)+u(0x1d5c5)+u(0x1d5be);
|
||||
|
||||
it("does not store an alias for related OutputTargets", function() {
|
||||
|
|
@ -263,7 +263,7 @@ but not himself.`; // Sheev Palpatine, in the Star Wars prequels.
|
|||
assert.equal(transcription.transform.deleteRight, 1, "Incorrect count for right-of-caret deletions");
|
||||
});
|
||||
|
||||
it("handles deletions around the caret without text insertion (SMP text)", function() {
|
||||
it("handles deletions around the caret without text insertion (non-BMP text)", function() {
|
||||
try {
|
||||
String.kmwEnableSupplementaryPlane(true);
|
||||
var target = new Mock(smpApple, 2);
|
||||
|
|
@ -355,7 +355,7 @@ but not himself.`; // Sheev Palpatine, in the Star Wars prequels.
|
|||
assert.equal(transcription.transform.deleteRight, 3, "Incorrect count for right-of-caret deletions");
|
||||
});
|
||||
|
||||
it("handles deletions around the caret with text insertion (SMP text)", function() {
|
||||
it("handles deletions around the caret with text insertion (non-BMP text)", function() {
|
||||
try {
|
||||
String.kmwEnableSupplementaryPlane(true);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ export { default as extendString } from "./kmwstring.js";
|
|||
export { default as ManagedPromise } from "./managedPromise.js";
|
||||
export { default as TimeoutPromise, timedPromise } from "./timeoutPromise.js";
|
||||
|
||||
export { Uni_IsSurrogate1, Uni_IsSurrogate2 } from "./surrogates.js";
|
||||
|
||||
// // Uncomment the following line and run the bundled output to verify successful
|
||||
// // esbuild bundling of this submodule:
|
||||
// console.log(Version.CURRENT.toString());
|
||||
27
common/web/utils/src/surrogates.ts
Normal file
27
common/web/utils/src/surrogates.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* The definitions below are duplicated from common/web/types/util/util.ts;
|
||||
* we can't downcompile the originals to ES5 when bundling with esbuild.
|
||||
* `import type` stuff is fine, but not non-type `import` statements.
|
||||
*
|
||||
* TODO: Use those instead, once we're no longer building ES5 versions of Web.
|
||||
*/
|
||||
|
||||
export const Uni_LEAD_SURROGATE_START = 0xD800;
|
||||
export const Uni_LEAD_SURROGATE_END = 0xDBFF;
|
||||
export const Uni_TRAIL_SURROGATE_START = 0xDC00;
|
||||
export const Uni_TRAIL_SURROGATE_END = 0xDFFF;
|
||||
|
||||
/**
|
||||
* @brief True if a lead surrogate
|
||||
* \def Uni_IsSurrogate1
|
||||
*/
|
||||
export function Uni_IsSurrogate1(ch : number) {
|
||||
return ((ch) >= Uni_LEAD_SURROGATE_START && (ch) <= Uni_LEAD_SURROGATE_END);
|
||||
}
|
||||
/**
|
||||
* @brief True if a trail surrogate
|
||||
* \def Uni_IsSurrogate2
|
||||
*/
|
||||
export function Uni_IsSurrogate2(ch : number) {
|
||||
return ((ch) >= Uni_TRAIL_SURROGATE_START && (ch) <= Uni_TRAIL_SURROGATE_END);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue