@mwater/visualization 5.4.0 → 5.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/ColorComponent.js +2 -1
- package/lib/IdSelection.d.ts +16 -0
- package/lib/IdSelection.js +59 -0
- package/lib/MWaterAddRelatedIndicatorComponent.js +2 -2
- package/lib/MWaterCompleteTableSelectComponent.d.ts +3 -8
- package/lib/MWaterCompleteTableSelectComponent.js +36 -42
- package/lib/MWaterLoaderComponent.d.ts +11 -10
- package/lib/MWaterLoaderComponent.js +1 -1
- package/lib/MWaterResponsesFilterComponent.js +1 -1
- package/lib/MWaterTableSelectComponent.d.ts +0 -1
- package/lib/MWaterTableSelectComponent.js +4 -6
- package/lib/autotranslate.d.ts +20 -0
- package/lib/autotranslate.js +122 -0
- package/lib/axes/AxisBuilder.js +3 -3
- package/lib/axes/AxisColorEditorComponent.js +4 -0
- package/lib/axes/AxisComponent.d.ts +8 -12
- package/lib/axes/AxisComponent.js +32 -80
- package/lib/axes/CategoryMapComponent.js +4 -4
- package/lib/axes/RangesComponent.js +2 -2
- package/lib/dashboards/DashboardComponent.d.ts +6 -0
- package/lib/dashboards/DashboardComponent.js +44 -12
- package/lib/dashboards/DashboardDesign.d.ts +11 -2
- package/lib/dashboards/DashboardUtils.d.ts +5 -0
- package/lib/dashboards/DashboardUtils.js +30 -0
- package/lib/dashboards/DashboardViewComponent.d.ts +2 -0
- package/lib/dashboards/DashboardViewComponent.js +16 -3
- package/lib/dashboards/ServerDashboardDataSource.js +2 -1
- package/lib/dashboards/SettingsModalComponent.d.ts +1 -1
- package/lib/dashboards/SettingsModalComponent.js +256 -19
- package/lib/dashboards/WidgetComponent.d.ts +6 -3
- package/lib/dashboards/WidgetComponent.js +3 -1
- package/lib/datagrids/CellEditor.d.ts +19 -0
- package/lib/datagrids/CellEditor.js +223 -0
- package/lib/datagrids/DatagridComponent.d.ts +18 -87
- package/lib/datagrids/DatagridComponent.js +304 -222
- package/lib/datagrids/DatagridViewComponent.d.ts +15 -53
- package/lib/datagrids/DatagridViewComponent.js +256 -257
- package/lib/datagrids/DirectDatagridDataSource.js +2 -3
- package/lib/datagrids/ExprCellComponent.d.ts +8 -15
- package/lib/datagrids/ExprCellComponent.js +11 -15
- package/lib/datagrids/FindReplaceModalComponent.d.ts +4 -6
- package/lib/datagrids/FindReplaceModalComponent.js +38 -75
- package/lib/index.css +1 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/layouts/blocks/HorizontalBlockComponent.js +2 -2
- package/lib/mWaterLoader.d.ts +1 -1
- package/lib/maps/BufferLayer.d.ts +7 -5
- package/lib/maps/BufferLayer.js +69 -48
- package/lib/maps/BufferLayerDesign.d.ts +21 -14
- package/lib/maps/BufferLayerDesignerComponent.d.ts +16 -31
- package/lib/maps/BufferLayerDesignerComponent.js +68 -102
- package/lib/maps/ChoroplethLayer.d.ts +5 -4
- package/lib/maps/ChoroplethLayer.js +32 -9
- package/lib/maps/ChoroplethLayerDesign.d.ts +6 -2
- package/lib/maps/ChoroplethLayerDesigner.js +4 -2
- package/lib/maps/ClusterLayer.d.ts +3 -4
- package/lib/maps/ClusterLayer.js +2 -1
- package/lib/maps/DetailLevelSelectComponent.js +1 -1
- package/lib/maps/DirectMapDataSource.js +2 -1
- package/lib/maps/EditPopupComponent.js +5 -3
- package/lib/maps/GridLayer.d.ts +3 -4
- package/lib/maps/GridLayer.js +2 -1
- package/lib/maps/GridLayerDesigner.js +5 -3
- package/lib/maps/HoverContent.d.ts +11 -3
- package/lib/maps/HoverContent.js +25 -9
- package/lib/maps/Layer.d.ts +24 -3
- package/lib/maps/Layer.js +5 -1
- package/lib/maps/LayerFactory.js +0 -8
- package/lib/maps/LayerLegendComponent.js +0 -1
- package/lib/maps/LayerSwitcherComponent.d.ts +1 -0
- package/lib/maps/LayerSwitcherComponent.js +1 -1
- package/lib/maps/LeafletMapComponent.js +3 -1
- package/lib/maps/LegendComponent.d.ts +1 -0
- package/lib/maps/LegendComponent.js +9 -1
- package/lib/maps/MWaterServerLayer.d.ts +2 -2
- package/lib/maps/MWaterServerLayer.js +2 -2
- package/lib/maps/MapComponent.js +3 -3
- package/lib/maps/MapDesign.d.ts +2 -0
- package/lib/maps/MapDesignerComponent.d.ts +4 -3
- package/lib/maps/MapDesignerComponent.js +68 -74
- package/lib/maps/MapLayerViewDesignerComponent.js +2 -2
- package/lib/maps/MapUtils.d.ts +4 -0
- package/lib/maps/MapUtils.js +19 -0
- package/lib/maps/MapViewComponent.d.ts +8 -3
- package/lib/maps/MarkersLayer.d.ts +5 -4
- package/lib/maps/MarkersLayer.js +33 -7
- package/lib/maps/MarkersLayerDesign.d.ts +19 -16
- package/lib/maps/PopupFilterJoinsUtils.d.ts +6 -3
- package/lib/maps/PopupFilterJoinsUtils.js +0 -6
- package/lib/maps/RasterMapViewComponent.d.ts +3 -31
- package/lib/maps/RasterMapViewComponent.js +7 -2
- package/lib/maps/ServerMapDataSource.js +2 -1
- package/lib/maps/SwitchableTileUrlLayer.d.ts +3 -3
- package/lib/maps/SwitchableTileUrlLayer.js +2 -1
- package/lib/maps/TileUrlLayer.d.ts +4 -5
- package/lib/maps/TileUrlLayer.js +2 -1
- package/lib/maps/VectorMapViewComponent.d.ts +5 -37
- package/lib/maps/VectorMapViewComponent.js +19 -8
- package/lib/maps/maps.d.ts +3 -0
- package/lib/quickfilter/QuickfiltersComponent.d.ts +2 -0
- package/lib/quickfilter/QuickfiltersComponent.js +9 -7
- package/lib/quickfilter/QuickfiltersDesignComponent.d.ts +1 -1
- package/lib/quickfilter/QuickfiltersDesignComponent.js +19 -35
- package/lib/richtext/ExprItemsHtmlConverter.d.ts +5 -2
- package/lib/richtext/ExprItemsHtmlConverter.js +4 -4
- package/lib/richtext/ExprItemsTranslator.d.ts +5 -0
- package/lib/richtext/ExprItemsTranslator.js +149 -0
- package/lib/richtext/ItemsHtmlConverter.d.ts +1 -1
- package/lib/richtext/ItemsHtmlConverter.js +31 -15
- package/lib/wellknown.js +12 -9
- package/lib/widgets/IFrameWidget.d.ts +4 -4
- package/lib/widgets/ImageWidget.d.ts +7 -4
- package/lib/widgets/ImageWidget.js +9 -1
- package/lib/widgets/ImageWidgetComponent.d.ts +1 -0
- package/lib/widgets/ImageWidgetComponent.js +1 -1
- package/lib/widgets/MapWidget.d.ts +5 -48
- package/lib/widgets/MapWidget.js +26 -63
- package/lib/widgets/MarkdownWidget.d.ts +3 -0
- package/lib/widgets/MarkdownWidget.js +3 -0
- package/lib/widgets/TOCWidget.d.ts +15 -27
- package/lib/widgets/TOCWidget.js +107 -183
- package/lib/widgets/Widget.d.ts +18 -7
- package/lib/widgets/Widget.js +4 -0
- package/lib/widgets/WidgetScopesViewComponent.js +1 -1
- package/lib/widgets/charts/Chart.d.ts +10 -1
- package/lib/widgets/charts/Chart.js +22 -11
- package/lib/widgets/charts/ChartViewComponent.d.ts +4 -0
- package/lib/widgets/charts/ChartViewComponent.js +6 -3
- package/lib/widgets/charts/ChartWidget.d.ts +2 -0
- package/lib/widgets/charts/ChartWidget.js +9 -1
- package/lib/widgets/charts/ChartWidgetComponent.d.ts +4 -0
- package/lib/widgets/charts/ChartWidgetComponent.js +2 -2
- package/lib/widgets/charts/calendar/CalendarChart.d.ts +1 -0
- package/lib/widgets/charts/calendar/CalendarChart.js +26 -0
- package/lib/widgets/charts/calendar/CalendarChartViewComponent.js +3 -1
- package/lib/widgets/charts/imagemosaic/ImageMosaicChart.d.ts +1 -0
- package/lib/widgets/charts/imagemosaic/ImageMosaicChart.js +8 -0
- package/lib/widgets/charts/layered/LayeredChart.d.ts +2 -0
- package/lib/widgets/charts/layered/LayeredChart.js +63 -3
- package/lib/widgets/charts/layered/LayeredChartCompiler.d.ts +1 -1
- package/lib/widgets/charts/layered/LayeredChartCompiler.js +3 -3
- package/lib/widgets/charts/layered/LayeredChartDesignerComponent.js +2 -2
- package/lib/widgets/charts/layered/LayeredChartViewComponent.js +8 -3
- package/lib/widgets/charts/pivot/PivotChart.d.ts +1 -0
- package/lib/widgets/charts/pivot/PivotChart.js +63 -0
- package/lib/widgets/charts/pivot/PivotChartDesignerComponent.d.ts +1 -0
- package/lib/widgets/charts/pivot/PivotChartLayoutComponent.js +1 -1
- package/lib/widgets/charts/pivot/SegmentDesignerComponent.d.ts +6 -0
- package/lib/widgets/charts/pivot/SegmentDesignerComponent.js +7 -4
- package/lib/widgets/charts/table/OrderingsComponent.js +1 -1
- package/lib/widgets/charts/table/TableChart.d.ts +1 -0
- package/lib/widgets/charts/table/TableChart.js +15 -0
- package/lib/widgets/text/TextComponent.d.ts +11 -4
- package/lib/widgets/text/TextComponent.js +11 -8
- package/lib/widgets/text/TextWidget.d.ts +6 -3
- package/lib/widgets/text/TextWidget.js +7 -1
- package/lib/widgets/text/TextWidgetComponent.d.ts +4 -0
- package/lib/widgets/text/TextWidgetComponent.js +7 -1
- package/lib/widgets/text/TextWidgetDesign.d.ts +2 -4
- package/lib/widgets/text/TextWidgetDesign.js +1 -1
- package/package.json +7 -8
- package/src/ColorComponent.tsx +1 -2
- package/src/IdSelection.ts +62 -0
- package/src/MWaterAddRelatedIndicatorComponent.ts +3 -2
- package/src/MWaterCompleteTableSelectComponent.tsx +36 -46
- package/src/MWaterLoaderComponent.ts +28 -26
- package/src/MWaterResponsesFilterComponent.ts +5 -2
- package/src/MWaterTableSelectComponent.tsx +5 -9
- package/src/autotranslate.ts +141 -0
- package/src/axes/AxisBuilder.ts +3 -3
- package/src/axes/AxisColorEditorComponent.tsx +5 -0
- package/src/axes/{AxisComponent.ts → AxisComponent.tsx} +106 -106
- package/src/axes/CategoryMapComponent.ts +4 -4
- package/src/axes/RangesComponent.ts +3 -2
- package/src/dashboards/DashboardComponent.tsx +79 -14
- package/src/dashboards/DashboardDesign.ts +9 -2
- package/src/dashboards/DashboardUtils.ts +39 -0
- package/src/dashboards/DashboardViewComponent.tsx +22 -3
- package/src/dashboards/ServerDashboardDataSource.ts +2 -1
- package/src/dashboards/SettingsModalComponent.tsx +450 -35
- package/src/dashboards/WidgetComponent.tsx +12 -6
- package/src/datagrids/CellEditor.tsx +354 -0
- package/src/datagrids/DatagridComponent.tsx +646 -0
- package/src/datagrids/DatagridViewComponent.tsx +539 -0
- package/src/datagrids/DirectDatagridDataSource.ts +2 -3
- package/src/datagrids/{ExprCellComponent.ts → ExprCellComponent.tsx} +28 -23
- package/src/datagrids/{FindReplaceModalComponent.ts → FindReplaceModalComponent.tsx} +109 -122
- package/src/index.css +1 -1
- package/src/index.ts +0 -1
- package/src/layouts/blocks/HorizontalBlockComponent.ts +2 -2
- package/src/mWaterLoader.ts +1 -1
- package/src/maps/BufferLayer.ts +83 -60
- package/src/maps/BufferLayerDesign.ts +20 -14
- package/src/maps/BufferLayerDesignerComponent.tsx +309 -0
- package/src/maps/ChoroplethLayer.ts +40 -19
- package/src/maps/ChoroplethLayerDesign.ts +4 -2
- package/src/maps/ChoroplethLayerDesigner.tsx +4 -2
- package/src/maps/ClusterLayer.ts +4 -10
- package/src/maps/DetailLevelSelectComponent.ts +1 -1
- package/src/maps/DirectMapDataSource.ts +2 -1
- package/src/maps/EditPopupComponent.ts +7 -3
- package/src/maps/GridLayer.ts +4 -10
- package/src/maps/GridLayerDesigner.tsx +5 -3
- package/src/maps/HoverContent.tsx +40 -16
- package/src/maps/Layer.ts +28 -10
- package/src/maps/LayerFactory.ts +0 -8
- package/src/maps/LayerLegendComponent.ts +2 -4
- package/src/maps/LayerSwitcherComponent.tsx +6 -2
- package/src/maps/LeafletMapComponent.tsx +3 -1
- package/src/maps/LegendComponent.tsx +10 -1
- package/src/maps/MWaterServerLayer.ts +3 -3
- package/src/maps/MapComponent.ts +3 -3
- package/src/maps/MapDesign.ts +3 -0
- package/src/maps/MapDesignerComponent.tsx +165 -162
- package/src/maps/MapLayerViewDesignerComponent.ts +2 -2
- package/src/maps/MapUtils.ts +24 -0
- package/src/maps/MapViewComponent.tsx +11 -3
- package/src/maps/MarkersLayer.ts +44 -18
- package/src/maps/MarkersLayerDesign.ts +19 -16
- package/src/maps/PopupFilterJoinsUtils.ts +6 -2
- package/src/maps/RasterMapViewComponent.ts +9 -45
- package/src/maps/ServerMapDataSource.ts +2 -2
- package/src/maps/SwitchableTileUrlLayer.tsx +4 -10
- package/src/maps/TileUrlLayer.tsx +4 -10
- package/src/maps/VectorMapViewComponent.tsx +28 -55
- package/src/maps/maps.ts +3 -0
- package/src/quickfilter/QuickfiltersComponent.ts +13 -7
- package/src/quickfilter/QuickfiltersDesignComponent.tsx +56 -74
- package/src/richtext/ExprItemsHtmlConverter.ts +9 -5
- package/src/richtext/ExprItemsTranslator.ts +176 -0
- package/src/richtext/ItemsHtmlConverter.ts +33 -18
- package/src/wellknown.ts +33 -30
- package/src/widgets/ImageWidget.ts +10 -1
- package/src/widgets/ImageWidgetComponent.ts +3 -2
- package/src/widgets/{MapWidget.ts → MapWidget.tsx} +90 -101
- package/src/widgets/MarkdownWidget.ts +3 -0
- package/src/widgets/TOCWidget.tsx +281 -0
- package/src/widgets/Widget.ts +25 -5
- package/src/widgets/WidgetScopesViewComponent.ts +2 -1
- package/src/widgets/charts/Chart.ts +31 -12
- package/src/widgets/charts/ChartViewComponent.ts +13 -3
- package/src/widgets/charts/ChartWidget.ts +11 -1
- package/src/widgets/charts/ChartWidgetComponent.tsx +9 -1
- package/src/widgets/charts/calendar/CalendarChart.ts +29 -0
- package/src/widgets/charts/calendar/CalendarChartViewComponent.tsx +3 -1
- package/src/widgets/charts/imagemosaic/ImageMosaicChart.ts +9 -0
- package/src/widgets/charts/layered/LayeredChart.ts +71 -3
- package/src/widgets/charts/layered/LayeredChartCompiler.ts +4 -4
- package/src/widgets/charts/layered/LayeredChartDesignerComponent.tsx +4 -2
- package/src/widgets/charts/layered/LayeredChartViewComponent.ts +10 -4
- package/src/widgets/charts/pivot/PivotChart.ts +73 -0
- package/src/widgets/charts/pivot/PivotChartLayoutComponent.tsx +1 -1
- package/src/widgets/charts/pivot/SegmentDesignerComponent.tsx +6 -4
- package/src/widgets/charts/table/OrderingsComponent.tsx +2 -1
- package/src/widgets/charts/table/TableChart.ts +17 -0
- package/src/widgets/text/TextComponent.tsx +22 -12
- package/src/widgets/text/TextWidget.ts +9 -2
- package/src/widgets/text/TextWidgetComponent.tsx +16 -1
- package/src/widgets/text/TextWidgetDesign.ts +4 -7
- package/test/IdSelectionTests.ts +54 -0
- package/test/LayeredChartCompilerTests.ts +0 -2
- package/test/richtext/ExprItemsTranslatorTests.ts +144 -0
- package/test/wellknownTests.ts +144 -0
- package/src/datagrids/DatagridComponent.ts +0 -478
- package/src/datagrids/DatagridViewComponent.ts +0 -464
- package/src/datagrids/EditExprCellComponent.tsx +0 -305
- package/src/datagrids/README.md +0 -3
- package/src/maps/BufferLayerDesignerComponent.ts +0 -311
- package/src/widgets/TOCWidget.ts +0 -326
- package/test/LegoLayoutEngineTests.ts +0 -69
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import _ from "lodash"
|
|
2
|
-
import ItemsHtmlConverter, { HtmlItemBase } from "./ItemsHtmlConverter"
|
|
2
|
+
import ItemsHtmlConverter, { HtmlItem, HtmlItemBase } from "./ItemsHtmlConverter"
|
|
3
3
|
import { Expr, ExprUtils, Schema } from "@mwater/expressions"
|
|
4
4
|
import uuid from "uuid"
|
|
5
5
|
import { formatValue } from "../valueFormatter"
|
|
6
6
|
import { canFormatType } from "../valueFormatter"
|
|
7
7
|
|
|
8
|
+
/** Html item that is an expression */
|
|
8
9
|
export interface HtmlItemExpr extends HtmlItemBase {
|
|
9
10
|
type: "expr"
|
|
10
11
|
|
|
@@ -24,6 +25,9 @@ export interface HtmlItemExpr extends HtmlItemBase {
|
|
|
24
25
|
format?: string
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
/** Html item that is an expression or a normal item */
|
|
29
|
+
export type HtmlItemOrExpr = HtmlItem | HtmlItemExpr
|
|
30
|
+
|
|
27
31
|
/**
|
|
28
32
|
* ItemsHtmlConverter that supports embedded mwater expressions
|
|
29
33
|
* Converts items (JSON contents of rich text) to HTML and back to allow editing
|
|
@@ -66,7 +70,7 @@ export default class ExprItemsHtmlConverter extends ItemsHtmlConverter {
|
|
|
66
70
|
if (this.summarizeExprs) {
|
|
67
71
|
text = new ExprUtils(this.schema).summarizeExpr(exprItem.expr, this.locale)
|
|
68
72
|
if (text.length > 30) {
|
|
69
|
-
text = text.substr(0, 30) +
|
|
73
|
+
text = text.substr(0, 30) + `...`
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
exprHtml = _.escape(text)
|
|
@@ -88,7 +92,7 @@ export default class ExprItemsHtmlConverter extends ItemsHtmlConverter {
|
|
|
88
92
|
|
|
89
93
|
exprHtml = _.escape(text)
|
|
90
94
|
} else {
|
|
91
|
-
exprHtml = `<span style="color: #DDD">${
|
|
95
|
+
exprHtml = `<span style="color: #DDD">${`---`}</span>`
|
|
92
96
|
}
|
|
93
97
|
} else {
|
|
94
98
|
// Placeholder
|
|
@@ -97,14 +101,14 @@ export default class ExprItemsHtmlConverter extends ItemsHtmlConverter {
|
|
|
97
101
|
|
|
98
102
|
// Add label
|
|
99
103
|
if (exprItem.includeLabel) {
|
|
100
|
-
const label = exprItem.labelText || new ExprUtils(this.schema).summarizeExpr(exprItem.expr, this.locale) +
|
|
104
|
+
const label = exprItem.labelText || new ExprUtils(this.schema).summarizeExpr(exprItem.expr, this.locale) + `:\u00A0`
|
|
101
105
|
exprHtml = `<span class="text-muted">${_.escape(label)}</span>` + exprHtml
|
|
102
106
|
}
|
|
103
107
|
|
|
104
108
|
if (this.designMode) {
|
|
105
109
|
html +=
|
|
106
110
|
`\u2060<span data-embed="${_.escape(JSON.stringify(item))}" class="mwater-visualization-text-widget-expr">` +
|
|
107
|
-
(exprHtml ||
|
|
111
|
+
(exprHtml || `\u00A0`) +
|
|
108
112
|
`</span>\u2060`
|
|
109
113
|
} else {
|
|
110
114
|
// View mode
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import _ from "lodash"
|
|
2
|
+
import { HtmlItemExpr, HtmlItemOrExpr } from "./ExprItemsHtmlConverter"
|
|
3
|
+
import { produce } from "immer"
|
|
4
|
+
import ItemsHtmlConverter, { HtmlItem, HtmlItemBase, HtmlItemElement } from "./ItemsHtmlConverter"
|
|
5
|
+
|
|
6
|
+
/** Gets all unique strings from html items */
|
|
7
|
+
export function getHtmlItemsStrings(items: HtmlItemOrExpr[]): string[] {
|
|
8
|
+
const strings = new Set<string>()
|
|
9
|
+
|
|
10
|
+
// Create collector function that just saves strings and returns them unchanged
|
|
11
|
+
const collectStrings = (str: string) => {
|
|
12
|
+
// Only collect non-empty strings
|
|
13
|
+
if (str) {
|
|
14
|
+
strings.add(str)
|
|
15
|
+
}
|
|
16
|
+
return str
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Use existing translation function but with collector
|
|
20
|
+
translateHtmlItems(items, collectStrings)
|
|
21
|
+
|
|
22
|
+
return Array.from(strings)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Translates items in an html items list with expressions */
|
|
26
|
+
export function translateHtmlItems(items: HtmlItemOrExpr[], translate: (input: string) => string): HtmlItemOrExpr[] {
|
|
27
|
+
return produce(items, draft => {
|
|
28
|
+
function translateItems(itemList: HtmlItemOrExpr[]) {
|
|
29
|
+
// Accumulate simple items
|
|
30
|
+
let simpleItems: HtmlItemOrExpr[] = []
|
|
31
|
+
let simpleItemStartIndex: number | null = null
|
|
32
|
+
|
|
33
|
+
/** Process accumulated simple nodes which are simple inline elements */
|
|
34
|
+
function processSimpleNodes() {
|
|
35
|
+
if (simpleItems.length === 0) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Create html string with {0}, {1}, etc. for expressions and html for other items
|
|
40
|
+
const expressions: HtmlItemExpr[] = []
|
|
41
|
+
|
|
42
|
+
const converter = new TranslationItemsHtmlConverter(item => {
|
|
43
|
+
if (item.type === "expr") {
|
|
44
|
+
const expr = item as HtmlItemExpr
|
|
45
|
+
if (expr.labelText) {
|
|
46
|
+
expr.labelText = translate(expr.labelText)
|
|
47
|
+
}
|
|
48
|
+
expressions.push(expr)
|
|
49
|
+
return `{${expressions.length - 1}}`
|
|
50
|
+
}
|
|
51
|
+
return ""
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
// Convert items to html which has the side effect of translating expressions
|
|
55
|
+
let html = converter.convertItemsToHtml(simpleItems)
|
|
56
|
+
|
|
57
|
+
// If there was no text, do nothing except translate expressions
|
|
58
|
+
if (!simpleItems.some(doesItemContainText)) {
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Remove leading and trailing whitespace from the HTML
|
|
63
|
+
const leftWhitespace = html.slice(0, html.length - html.trimStart().length)
|
|
64
|
+
const rightWhitespace = html.slice(html.trimEnd().length)
|
|
65
|
+
html = html.trim()
|
|
66
|
+
|
|
67
|
+
if (!html) {
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let translatedHtml = leftWhitespace + translate(html) + rightWhitespace
|
|
72
|
+
|
|
73
|
+
// Parse translatedHtml into items by first replacing {0}, {1}, etc. with html that can be converted to items
|
|
74
|
+
for (let i = 0; i < expressions.length; i++) {
|
|
75
|
+
const expr = expressions[i]
|
|
76
|
+
translatedHtml = translatedHtml.replace(new RegExp(`\\{${i}\\}`, "g"), `<span data-embed="${_.escape(JSON.stringify(expr))}"></span>`)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Wrap in a div to prevent whitespace from being trimmed.
|
|
80
|
+
const translatedItems = (converter.convertElemToItems(new DOMParser().parseFromString("<div>" + translatedHtml + "</div>", "text/html").body.firstChild as HTMLElement))
|
|
81
|
+
|
|
82
|
+
// Replace the simple items with the translated items
|
|
83
|
+
itemList.splice(simpleItemStartIndex!, simpleItems.length, ...translatedItems)
|
|
84
|
+
|
|
85
|
+
simpleItems = []
|
|
86
|
+
simpleItemStartIndex = null
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
for (let i = 0; i < itemList.length; i++) {
|
|
90
|
+
const item = itemList[i]
|
|
91
|
+
|
|
92
|
+
// If the child is a simple node, add it to the list
|
|
93
|
+
if (isItemSimple(item)) {
|
|
94
|
+
simpleItems.push(item)
|
|
95
|
+
if (simpleItemStartIndex == null) {
|
|
96
|
+
simpleItemStartIndex = i
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
// If we have gathered simple nodes, we need to return/replace them
|
|
100
|
+
processSimpleNodes()
|
|
101
|
+
simpleItemStartIndex = null
|
|
102
|
+
simpleItems = []
|
|
103
|
+
|
|
104
|
+
// Handle the current node
|
|
105
|
+
if (typeof item !== "string" && item.type === "element" && item.items) {
|
|
106
|
+
translateItems(item.items)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (simpleItems.length > 0) {
|
|
112
|
+
processSimpleNodes()
|
|
113
|
+
simpleItemStartIndex = null
|
|
114
|
+
simpleItems = []
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
translateItems(draft)
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** ItemsHtmlConverter that has a callback for handling special items */
|
|
123
|
+
class TranslationItemsHtmlConverter extends ItemsHtmlConverter {
|
|
124
|
+
handleSpecialItem: (item: HtmlItemBase) => string
|
|
125
|
+
|
|
126
|
+
constructor(handleSpecialItem: (item: HtmlItemBase) => string) {
|
|
127
|
+
super()
|
|
128
|
+
this.handleSpecialItem = handleSpecialItem
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
convertSpecialItemToHtml(item: HtmlItemBase) {
|
|
132
|
+
return this.handleSpecialItem(item)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Check if an html item is simple.
|
|
138
|
+
* A node is simple if it is:
|
|
139
|
+
* - a string
|
|
140
|
+
* - a tag that is a "b", "i", "u", "a", "strong", "em" tag with no children or only simple children
|
|
141
|
+
* Only sequences of simple nodes are exported to translation entries as HTML.
|
|
142
|
+
*/
|
|
143
|
+
function isItemSimple(node: HtmlItemOrExpr): boolean {
|
|
144
|
+
if (typeof node === "string") {
|
|
145
|
+
return true
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (node.type === "expr") {
|
|
149
|
+
return true
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (node.type === "element") {
|
|
153
|
+
const element = node as HtmlItemElement
|
|
154
|
+
|
|
155
|
+
if (["b", "i", "u", "a", "strong", "em"].indexOf(element.tag) === -1) {
|
|
156
|
+
return false
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return (element.items || []).every(child => isItemSimple(child))
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return false
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Determines if an item contains any non-empty text strings */
|
|
166
|
+
function doesItemContainText(item: HtmlItemOrExpr): boolean {
|
|
167
|
+
if (typeof item === "string") {
|
|
168
|
+
return item.trim().length > 0
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (item.type === "element") {
|
|
172
|
+
return (item.items || []).some(child => doesItemContainText(child))
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return false
|
|
176
|
+
}
|
|
@@ -47,7 +47,7 @@ export default class ItemsHtmlConverter {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
// Converts list of items to html
|
|
50
|
-
convertItemsToHtml(items:
|
|
50
|
+
convertItemsToHtml(items: HtmlItem[]) {
|
|
51
51
|
let html = ""
|
|
52
52
|
|
|
53
53
|
for (let item of items || []) {
|
|
@@ -66,19 +66,20 @@ export default class ItemsHtmlConverter {
|
|
|
66
66
|
// Escape HTML
|
|
67
67
|
html += _.escape(itemStr)
|
|
68
68
|
} else if (item.type === "element") {
|
|
69
|
-
|
|
69
|
+
const element = item as HtmlItemElement
|
|
70
|
+
if (!allowedTags[element.tag]) {
|
|
70
71
|
// Ignore and do contents
|
|
71
|
-
html += this.convertItemsToHtml(
|
|
72
|
+
html += this.convertItemsToHtml(element.items || [])
|
|
72
73
|
continue
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
let attrs = ""
|
|
76
77
|
// Add style
|
|
77
|
-
if (
|
|
78
|
+
if (element.style) {
|
|
78
79
|
attrs += ' style="'
|
|
79
80
|
let first = true
|
|
80
|
-
for (let key in
|
|
81
|
-
const value =
|
|
81
|
+
for (let key in element.style) {
|
|
82
|
+
const value = element.style[key]
|
|
82
83
|
if (!allowedStyles[key]) {
|
|
83
84
|
continue
|
|
84
85
|
}
|
|
@@ -97,20 +98,20 @@ export default class ItemsHtmlConverter {
|
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
// Add href
|
|
100
|
-
if (
|
|
101
|
-
attrs += ' href="' +
|
|
101
|
+
if (element.href) {
|
|
102
|
+
attrs += ' href="' + element.href + '"'
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
// Add target
|
|
105
|
-
if (
|
|
106
|
-
attrs += ' target="' + _.escape(
|
|
106
|
+
if (element.target) {
|
|
107
|
+
attrs += ' target="' + _.escape(element.target) + '"'
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
// Special case for self-closing tags
|
|
110
|
-
if (["br"].includes(
|
|
111
|
-
html += `<${
|
|
111
|
+
if (["br"].includes(element.tag)) {
|
|
112
|
+
html += `<${element.tag}${attrs}>`
|
|
112
113
|
} else {
|
|
113
|
-
html += `<${
|
|
114
|
+
html += `<${element.tag}${attrs}>` + this.convertItemsToHtml(element.items || []) + `</${element.tag}>`
|
|
114
115
|
}
|
|
115
116
|
} else {
|
|
116
117
|
html += this.convertSpecialItemToHtml(item)
|
|
@@ -123,6 +124,8 @@ export default class ItemsHtmlConverter {
|
|
|
123
124
|
}
|
|
124
125
|
|
|
125
126
|
// console.log "createHtml: #{html}"
|
|
127
|
+
// console.log("convertItemsToHtml: " + JSON.stringify(items, null, 2))
|
|
128
|
+
// console.log("convertItemsToHtml: " + html)
|
|
126
129
|
return html
|
|
127
130
|
}
|
|
128
131
|
|
|
@@ -168,16 +171,22 @@ export default class ItemsHtmlConverter {
|
|
|
168
171
|
const nodeElement = node as HTMLElement
|
|
169
172
|
if (nodeElement.style != null) {
|
|
170
173
|
const styleDeclaration = nodeElement.style
|
|
171
|
-
for (
|
|
172
|
-
|
|
174
|
+
for (let i = 0; i < styleDeclaration.length; i++) {
|
|
175
|
+
const style = styleDeclaration[i]
|
|
176
|
+
if (!allowedStyles[style]) {
|
|
173
177
|
continue
|
|
174
178
|
}
|
|
175
179
|
|
|
176
|
-
const value = styleDeclaration
|
|
180
|
+
const value = styleDeclaration.getPropertyValue(style)
|
|
177
181
|
if (value == null || value === "") {
|
|
178
182
|
continue
|
|
179
183
|
}
|
|
180
184
|
|
|
185
|
+
// Ignore bootstrap variables in style values
|
|
186
|
+
if (value.startsWith("var(--bs-")) {
|
|
187
|
+
continue
|
|
188
|
+
}
|
|
189
|
+
|
|
181
190
|
item.style = item.style || {}
|
|
182
191
|
item.style[style] = value
|
|
183
192
|
}
|
|
@@ -203,7 +212,12 @@ export default class ItemsHtmlConverter {
|
|
|
203
212
|
item.target = (node as HTMLLinkElement).target
|
|
204
213
|
}
|
|
205
214
|
|
|
206
|
-
|
|
215
|
+
// Unwrap pointless span elements that have no style and one child
|
|
216
|
+
if (tag === "span" && item.style == null && item.items?.length === 1) {
|
|
217
|
+
items.push(item.items[0])
|
|
218
|
+
} else {
|
|
219
|
+
items.push(item)
|
|
220
|
+
}
|
|
207
221
|
|
|
208
222
|
// Handle text
|
|
209
223
|
} else if (node.nodeType === 3) {
|
|
@@ -218,7 +232,8 @@ export default class ItemsHtmlConverter {
|
|
|
218
232
|
}
|
|
219
233
|
|
|
220
234
|
// console.log JSON.stringify(items, null, 2)
|
|
221
|
-
|
|
235
|
+
// console.log("convertElemToItems: " + elem.outerHTML)
|
|
236
|
+
// console.log("convertElemToItems: " + JSON.stringify(items, null, 2))
|
|
222
237
|
return items
|
|
223
238
|
}
|
|
224
239
|
}
|
package/src/wellknown.ts
CHANGED
|
@@ -21,7 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
21
21
|
|
|
22
22
|
const numberRegexp: RegExp = /[-+]?([0-9]*\.[0-9]+|[0-9]+)([eE][-+]?[0-9]+)?/;
|
|
23
23
|
// Matches sequences like '100 100' or '100 100 100'.
|
|
24
|
-
const tuples: RegExp = new RegExp('^' + numberRegexp.source + '(\\s' + numberRegexp.source + '){1,}');
|
|
24
|
+
const tuples: RegExp = new RegExp('^' + numberRegexp.source + '(\\s' + numberRegexp.source + '){1,3}');
|
|
25
25
|
|
|
26
26
|
/*
|
|
27
27
|
* Parse WKT and return GeoJSON.
|
|
@@ -61,12 +61,12 @@ export function parse(input: string): any {
|
|
|
61
61
|
function white(): void { $(/^\s*/); }
|
|
62
62
|
|
|
63
63
|
function multicoords(): any[] | null {
|
|
64
|
-
white()
|
|
65
|
-
let depth: number = 0
|
|
66
|
-
let rings: any[] = []
|
|
67
|
-
let stack: any[][] = [rings]
|
|
68
|
-
let pointer: any[] = rings
|
|
69
|
-
let elem: string | null
|
|
64
|
+
white()
|
|
65
|
+
let depth: number = 0
|
|
66
|
+
let rings: any[] = []
|
|
67
|
+
let stack: any[][] = [rings]
|
|
68
|
+
let pointer: any[] = rings
|
|
69
|
+
let elem: string | null
|
|
70
70
|
|
|
71
71
|
while (elem =
|
|
72
72
|
$(/^(\()/) ||
|
|
@@ -74,33 +74,35 @@ export function parse(input: string): any {
|
|
|
74
74
|
$(/^(,)/) ||
|
|
75
75
|
$(tuples)) {
|
|
76
76
|
if (elem === '(') {
|
|
77
|
-
stack.push(pointer)
|
|
78
|
-
pointer = []
|
|
79
|
-
stack[stack.length - 1].push(pointer)
|
|
80
|
-
depth
|
|
77
|
+
stack.push(pointer)
|
|
78
|
+
pointer = []
|
|
79
|
+
stack[stack.length - 1].push(pointer)
|
|
80
|
+
depth++
|
|
81
81
|
} else if (elem === ')') {
|
|
82
82
|
// For the case: Polygon(), ...
|
|
83
|
-
if (pointer.length === 0) return null
|
|
83
|
+
if (pointer.length === 0) return null
|
|
84
84
|
|
|
85
|
-
pointer = stack.pop() || []
|
|
85
|
+
pointer = stack.pop() || []
|
|
86
86
|
// the stack was empty, input was malformed
|
|
87
|
-
if (!pointer) return null
|
|
88
|
-
depth
|
|
89
|
-
if (depth === 0) break
|
|
87
|
+
if (!pointer) return null
|
|
88
|
+
depth--
|
|
89
|
+
if (depth === 0) break
|
|
90
90
|
} else if (elem === ',') {
|
|
91
|
-
pointer = []
|
|
92
|
-
stack[stack.length - 1].push(pointer)
|
|
91
|
+
pointer = []
|
|
92
|
+
stack[stack.length - 1].push(pointer)
|
|
93
93
|
} else if (!elem.split(/\s/g).some(s => isNaN(s as any))) {
|
|
94
|
-
|
|
94
|
+
// Split into values and only take first 3 if there are 4 (ZM coordinates)
|
|
95
|
+
const values = elem.split(/\s/g).map(parseFloat)
|
|
96
|
+
Array.prototype.push.apply(pointer, values.length === 4 ? values.slice(0, 3) : values)
|
|
95
97
|
} else {
|
|
96
|
-
return null
|
|
98
|
+
return null
|
|
97
99
|
}
|
|
98
|
-
white()
|
|
100
|
+
white()
|
|
99
101
|
}
|
|
100
102
|
|
|
101
|
-
if (depth !== 0) return null
|
|
103
|
+
if (depth !== 0) return null
|
|
102
104
|
|
|
103
|
-
return rings
|
|
105
|
+
return rings
|
|
104
106
|
}
|
|
105
107
|
|
|
106
108
|
function coords(): any[] | null {
|
|
@@ -115,7 +117,8 @@ export function parse(input: string): any {
|
|
|
115
117
|
item = [];
|
|
116
118
|
} else if (!pt.split(/\s/g).some(s => isNaN(s as any))) {
|
|
117
119
|
if (!item) item = [];
|
|
118
|
-
|
|
120
|
+
const values = pt.split(/\s/g).map(parseFloat)
|
|
121
|
+
Array.prototype.push.apply(item, values.length === 4 ? values.slice(0, 3) : values);
|
|
119
122
|
}
|
|
120
123
|
white();
|
|
121
124
|
}
|
|
@@ -127,7 +130,7 @@ export function parse(input: string): any {
|
|
|
127
130
|
}
|
|
128
131
|
|
|
129
132
|
function point(): any | null {
|
|
130
|
-
if (!$(/^(point(\
|
|
133
|
+
if (!$(/^(point(\s+zm|\s+z)?)/i)) return null;
|
|
131
134
|
white();
|
|
132
135
|
if (!$(/^(\()/)) return null;
|
|
133
136
|
let c: any[] | null = coords();
|
|
@@ -141,7 +144,7 @@ export function parse(input: string): any {
|
|
|
141
144
|
}
|
|
142
145
|
|
|
143
146
|
function multipoint(): any | null {
|
|
144
|
-
if (!$(/^(multipoint(\
|
|
147
|
+
if (!$(/^(multipoint(\s+zm|\s+z)?)/i)) return null;
|
|
145
148
|
white();
|
|
146
149
|
let newCoordsFormat: string = _!
|
|
147
150
|
.substring(_!.indexOf('(') + 1, _!.length - 1)
|
|
@@ -158,7 +161,7 @@ export function parse(input: string): any {
|
|
|
158
161
|
}
|
|
159
162
|
|
|
160
163
|
function multilinestring(): any | null {
|
|
161
|
-
if (!$(/^(multilinestring(\
|
|
164
|
+
if (!$(/^(multilinestring(\s+zm|\s+z)?)/i)) return null;
|
|
162
165
|
white();
|
|
163
166
|
let c: any[] | null = multicoords();
|
|
164
167
|
if (!c) return null;
|
|
@@ -170,7 +173,7 @@ export function parse(input: string): any {
|
|
|
170
173
|
}
|
|
171
174
|
|
|
172
175
|
function linestring(): any | null {
|
|
173
|
-
if (!$(/^(linestring(\
|
|
176
|
+
if (!$(/^(linestring(\s+zm|\s+z)?)/i)) return null;
|
|
174
177
|
white();
|
|
175
178
|
if (!$(/^(\()/)) return null;
|
|
176
179
|
let c: any[] | null = coords();
|
|
@@ -183,7 +186,7 @@ export function parse(input: string): any {
|
|
|
183
186
|
}
|
|
184
187
|
|
|
185
188
|
function polygon(): any | null {
|
|
186
|
-
if (!$(/^(polygon(\
|
|
189
|
+
if (!$(/^(polygon(\s+zm|\s+z)?)/i)) return null;
|
|
187
190
|
white();
|
|
188
191
|
let c: any[] | null = multicoords();
|
|
189
192
|
if (!c) return null;
|
|
@@ -194,7 +197,7 @@ export function parse(input: string): any {
|
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
function multipolygon(): any | null {
|
|
197
|
-
if (!$(/^(multipolygon(\
|
|
200
|
+
if (!$(/^(multipolygon(\s+zm|\s+z)?)/i)) return null;
|
|
198
201
|
white();
|
|
199
202
|
let c: any[] | null = multicoords();
|
|
200
203
|
if (!c) return null;
|
|
@@ -62,7 +62,8 @@ export default class ImageWidget extends Widget {
|
|
|
62
62
|
onDesignChange: options.onDesignChange,
|
|
63
63
|
width: options.width,
|
|
64
64
|
height: options.height,
|
|
65
|
-
singleRowTable: options.singleRowTable
|
|
65
|
+
singleRowTable: options.singleRowTable,
|
|
66
|
+
translate: options.translate
|
|
66
67
|
})
|
|
67
68
|
}
|
|
68
69
|
|
|
@@ -144,4 +145,12 @@ export default class ImageWidget extends Widget {
|
|
|
144
145
|
|
|
145
146
|
return []
|
|
146
147
|
}
|
|
148
|
+
|
|
149
|
+
getTranslatableStrings(design: ImageWidgetDesign, schema: Schema): string[] {
|
|
150
|
+
const strings: string[] = []
|
|
151
|
+
if (design.caption) {
|
|
152
|
+
strings.push(design.caption)
|
|
153
|
+
}
|
|
154
|
+
return strings
|
|
155
|
+
}
|
|
147
156
|
}
|
|
@@ -29,6 +29,7 @@ export interface ImageWidgetComponentProps {
|
|
|
29
29
|
width: number
|
|
30
30
|
height: number
|
|
31
31
|
singleRowTable?: string
|
|
32
|
+
translate: (input: string) => string
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
export default class ImageWidgetComponent extends AsyncLoadComponent<ImageWidgetComponentProps, { data: any, loading: boolean }> {
|
|
@@ -154,9 +155,9 @@ export default class ImageWidgetComponent extends AsyncLoadComponent<ImageWidget
|
|
|
154
155
|
className: "mwater-visualization-image-widget",
|
|
155
156
|
style: { position: "relative", width: this.props.width, height: this.props.height }
|
|
156
157
|
},
|
|
157
|
-
captionPosition === "top" ? R("div", { className: "caption" }, this.props.design.caption) : undefined,
|
|
158
|
+
captionPosition === "top" && this.props.design.caption ? R("div", { className: "caption" }, this.props.translate(this.props.design.caption)) : undefined,
|
|
158
159
|
R("div", { className: "image" }, this.renderContent()),
|
|
159
|
-
captionPosition === "bottom" ? R("div", { className: "caption" }, this.props.design.caption) : undefined
|
|
160
|
+
captionPosition === "bottom" && this.props.design.caption ? R("div", { className: "caption" }, this.props.translate(this.props.design.caption)) : undefined
|
|
160
161
|
)
|
|
161
162
|
)
|
|
162
163
|
}
|