Skip to content

Commit

Permalink
more robust language switching
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanlurie committed Nov 6, 2024
1 parent 71216af commit 67562dc
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 14 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## 2.4.2
### Bug Fixes
- The language switching is now more robust and preserves the original formatting from the style (`Map.setPrimareyLangage()`) (https://github.com/maptiler/maptiler-sdk-js/pull/134)
- The language switching is now more robust and preserves the original formatting from the style (`Map.setPrimaryLangage()`) (https://github.com/maptiler/maptiler-sdk-js/pull/134)

## 2.4.1
### Bug Fixes
Expand Down
27 changes: 16 additions & 11 deletions src/Map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ import { defaults } from "./defaults";
import { MaptilerLogoControl } from "./MaptilerLogoControl";
import {
changeFirstLanguage,
checkNamePattern,
combineTransformRequest,
displayNoWebGlWarning,
displayWebGLContextLostWarning,
replaceLanguage,
} from "./tools";
import { getBrowserLanguage, Language, type LanguageInfo } from "./language";
import { styleToStyle } from "./mapstyle";
Expand Down Expand Up @@ -1127,19 +1129,22 @@ export class Map extends maplibregl.Map {

// Testing the different case where the text-field property should NOT be updated:
if (typeof textFieldLayoutProp === "string") {
// If the field is a string that DOES NOT contain an opening curly bracket.
// (This happens when the label is a hardcoded string that does not refer to a property)
if (!textFieldLayoutProp.includes("{")) {
continue;
}
const { contains, exactMatch } = checkNamePattern(textFieldLayoutProp);

// If the text field does not contain the "name" substring.
// This happens when dealing with {ref}, {housenumber}, {height}, etc.
if (!textFieldLayoutProp.includes("name")) {
continue;
}
// If the current text-fiels does not contain any "{name:xx}" pattern
if (!contains) continue;

this.setLayoutProperty(id, "text-field", replacer);
// In case of an exact match, we replace by an object representation of the label
if (exactMatch) {
this.setLayoutProperty(id, "text-field", replacer);
} else {
// In case of a non-exact match (such as "foo {name:xx} bar")
// we create a "concat" object expresion composed of the original elements with new replacer
// in-betweem
const newReplacer = replaceLanguage(textFieldLayoutProp, replacer);

this.setLayoutProperty(id, "text-field", newReplacer);
}
}

// The value of text-field is an object
Expand Down
28 changes: 28 additions & 0 deletions src/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,31 @@ export function changeFirstLanguage(
exploreNode(expr);
return expr;
}

/**
* Tst if a string matches the pattern "{name:xx}" in a exact way or is a loose way (such as "foo {name:xx}")
*/
export function checkNamePattern(str: string): { contains: boolean; exactMatch: boolean } {
const regex = /\{name:[a-zA-Z]{2}\}/;
return {
contains: regex.test(str),
exactMatch: new RegExp(`^${regex.source}$`).test(str),
};
}

/**
* Replaces the occurences of {name:xx} in a string by a provided object-expression to return a concat object expression
*/
export function replaceLanguage(
origLang: string,
newLang: maplibregl.ExpressionSpecification,
): maplibregl.ExpressionSpecification {
const elementsToConcat = origLang.split(/\{name:[a-zA-Z]{2}\}/);

const allElements = elementsToConcat.flatMap((item, i) =>
i === elementsToConcat.length - 1 ? [item] : [item, newLang],
);

const expr = ["concat", ...allElements] as maplibregl.ExpressionSpecification;
return expr;
}
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"compilerOptions": {
"baseUrl": "src",
"moduleResolution": "Node",
"target": "ES2020",
"target": "es2021",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"lib": ["es2021", "DOM", "DOM.Iterable"],
"skipLibCheck": true,

/* Bundler mode */
Expand Down

0 comments on commit 67562dc

Please sign in to comment.