Skip to content

Commit ae5df55

Browse files
authored
fix: evaluate variable string and type issue on credits (#86)
1 parent 7aab1a5 commit ae5df55

4 files changed

Lines changed: 86 additions & 15 deletions

File tree

src/engines/Cesium/common.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import { DEFAULT_SCREEN_SPACE_CAMERA_ASSIGNMENTS } from "./constants";
5858
export const layerIdField = `__reearth_layer_id`;
5959

6060
const defaultImageSize = 50;
61+
const emptyCredites: Credits = { engine: {}, lightbox: [], screen: [] };
6162

6263
const drawIcon = (
6364
image: HTMLImageElement | undefined,
@@ -904,7 +905,7 @@ export function getExtrudedHeight(
904905
}
905906

906907
export function getCredits(viewer: Viewer) {
907-
if (!viewer) return;
908+
if (!viewer) return emptyCredites;
908909
const creditDisplay = viewer.creditDisplay as
909910
| (CreditDisplay & {
910911
_currentFrameCredits: {
@@ -915,7 +916,7 @@ export function getCredits(viewer: Viewer) {
915916
})
916917
| undefined;
917918

918-
if (!creditDisplay) return;
919+
if (!creditDisplay) return emptyCredites;
919920

920921
const { lightboxCredits, screenCredits } = creditDisplay?._currentFrameCredits || {};
921922
const cesiumCredits = creditDisplay._currentCesiumCredit;

src/engines/Cesium/hooks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ export default ({
130130
onLayerLoad?: (e: LayerLoadEvent) => void;
131131
onCameraChange?: (camera: Camera) => void;
132132
onMount?: () => void;
133-
onCreditsUpdate?: (credits?: Credits) => void;
133+
onCreditsUpdate?: (credits: Credits) => void;
134134
}) => {
135135
const cesium = useRef<CesiumComponentRef<CesiumViewer>>(null);
136136

src/mantle/evaluator/simple/expression/expression.test.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ describe("replaceDefines", () => {
2626
});
2727
expect(result).toBe("(value1) + (value2)");
2828
});
29+
30+
test("should handle Japanese text with multiple variables", () => {
31+
const result = replaceDefines("${住所} (${人数}人)", {
32+
住所: "東京都渋谷区",
33+
人数: "5",
34+
});
35+
expect(result).toBe("(東京都渋谷区) ((5)人)");
36+
});
2937
});
3038

3139
describe("removeBackslashes", () => {
@@ -40,6 +48,70 @@ describe("removeBackslashes", () => {
4048
});
4149
});
4250

51+
describe("Expression evaluation", () => {
52+
test("should evaluate Japanese expression with feature properties as string literal", () => {
53+
const expressionString = '"${住所} (${人数}人)"';
54+
const feature = {
55+
properties: {
56+
住所: "緑町",
57+
人数: 2,
58+
},
59+
} as Feature;
60+
61+
const expression = new Expression(expressionString, feature);
62+
const result = expression.evaluate();
63+
64+
expect(result).toBe("緑町 (2人)");
65+
});
66+
67+
test("should evaluate Japanese expression with two spaces - user observation", () => {
68+
const expressionString = '"${住所} (${人数}人)"';
69+
const feature = {
70+
properties: {
71+
住所: "緑町",
72+
人数: 2,
73+
},
74+
} as Feature;
75+
76+
const expression = new Expression(expressionString, feature);
77+
const result = expression.evaluate();
78+
79+
expect(result).toBe("緑町 (2人)");
80+
});
81+
82+
test("should evaluate expression with multiple variables", () => {
83+
const expressionString = '"${name}: ${住所} (${人数}人) - ${status}"';
84+
const feature = {
85+
properties: {
86+
name: "太郎",
87+
住所: "緑町",
88+
人数: 2,
89+
status: "完了",
90+
},
91+
} as Feature;
92+
93+
const expression = new Expression(expressionString, feature);
94+
const result = expression.evaluate();
95+
96+
expect(result).toBe("太郎: 緑町 (2人) - 完了");
97+
});
98+
99+
test("should evaluate Japanese expression without quotes - shows the issue", () => {
100+
const expressionString = "${住所} (${人数}人)";
101+
const feature = {
102+
properties: {
103+
住所: "緑町",
104+
人数: 2,
105+
},
106+
} as Feature;
107+
108+
expect(() => {
109+
const expression = new Expression(expressionString, feature);
110+
expression.evaluate();
111+
}).toThrow('Unexpected function call "czm_住所"');
112+
});
113+
});
114+
43115
describe("expression caches", () => {
44116
beforeEach(() => {
45117
EXPRESSION_CACHES.clear();

src/mantle/evaluator/simple/expression/node.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -175,18 +175,16 @@ export class Node {
175175
}
176176
_evaluateVariableString(feature?: Feature) {
177177
const variableRegex = /\${(.*?)}/g;
178-
let result = this._value;
179-
let match = variableRegex.exec(result);
180-
while (match !== null) {
181-
const placeholder = match[0];
182-
const variableName = match[1];
183-
let property = feature?.properties[variableName];
184-
if (typeof property === "undefined") {
185-
property = "";
186-
}
187-
result = result.replace(placeholder, property);
188-
match = variableRegex.exec(result);
189-
}
178+
const result = this._value.replace(
179+
variableRegex,
180+
(_placeholder: string, variableName: string) => {
181+
let property = feature?.properties[variableName];
182+
if (typeof property === "undefined") {
183+
property = "";
184+
}
185+
return property;
186+
},
187+
);
190188
return result;
191189
}
192190
_evaluateVariable(feature?: Feature) {

0 commit comments

Comments
 (0)