@trebco/treb 36.1.4 → 37.0.1
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/api-config.json +1 -1
- package/build/package.json +119 -0
- package/build/treb-base-types/src/api_types.d.ts +11 -0
- package/build/treb-base-types/src/api_types.js +22 -0
- package/build/treb-base-types/src/api_types.js.map +1 -0
- package/build/treb-base-types/src/area-utils.d.ts +9 -0
- package/build/treb-base-types/src/area-utils.js +50 -0
- package/build/treb-base-types/src/area-utils.js.map +1 -0
- package/build/treb-base-types/src/area.d.ts +182 -0
- package/build/treb-base-types/src/area.js +715 -0
- package/build/treb-base-types/src/area.js.map +1 -0
- package/build/treb-base-types/src/basic_types.d.ts +20 -0
- package/build/treb-base-types/src/basic_types.js +22 -0
- package/build/treb-base-types/src/basic_types.js.map +1 -0
- package/build/treb-base-types/src/cell.d.ts +167 -0
- package/build/treb-base-types/src/cell.js +432 -0
- package/build/treb-base-types/src/cell.js.map +1 -0
- package/build/treb-base-types/src/cells.d.ts +251 -0
- package/build/treb-base-types/src/cells.js +1136 -0
- package/build/treb-base-types/src/cells.js.map +1 -0
- package/build/treb-base-types/src/color.d.ts +35 -0
- package/build/treb-base-types/src/color.js +162 -0
- package/build/treb-base-types/src/color.js.map +1 -0
- package/build/treb-base-types/src/dom-utilities.d.ts +70 -0
- package/build/treb-base-types/src/dom-utilities.js +144 -0
- package/build/treb-base-types/src/dom-utilities.js.map +1 -0
- package/build/treb-base-types/src/evaluate-options.d.ts +35 -0
- package/build/treb-base-types/src/evaluate-options.js +22 -0
- package/build/treb-base-types/src/evaluate-options.js.map +1 -0
- package/build/treb-base-types/src/font-stack.d.ts +37 -0
- package/build/treb-base-types/src/font-stack.js +93 -0
- package/build/treb-base-types/src/font-stack.js.map +1 -0
- package/build/treb-base-types/src/gradient.d.ts +18 -0
- package/build/treb-base-types/src/gradient.js +86 -0
- package/build/treb-base-types/src/gradient.js.map +1 -0
- package/build/treb-base-types/src/import.d.ts +48 -0
- package/build/treb-base-types/src/import.js +22 -0
- package/build/treb-base-types/src/import.js.map +1 -0
- package/build/treb-base-types/src/index-standalone.d.ts +6 -0
- package/build/treb-base-types/src/index-standalone.js +27 -0
- package/build/treb-base-types/src/index-standalone.js.map +1 -0
- package/build/treb-base-types/src/index.d.ts +22 -0
- package/build/treb-base-types/src/index.js +45 -0
- package/build/treb-base-types/src/index.js.map +1 -0
- package/build/treb-base-types/src/layout.d.ts +22 -0
- package/build/treb-base-types/src/layout.js +22 -0
- package/build/treb-base-types/src/layout.js.map +1 -0
- package/build/treb-base-types/src/localization.d.ts +37 -0
- package/build/treb-base-types/src/localization.js +157 -0
- package/build/treb-base-types/src/localization.js.map +1 -0
- package/build/treb-base-types/src/rectangle.d.ts +51 -0
- package/build/treb-base-types/src/rectangle.js +123 -0
- package/build/treb-base-types/src/rectangle.js.map +1 -0
- package/build/treb-base-types/src/render_text.d.ts +34 -0
- package/build/treb-base-types/src/render_text.js +22 -0
- package/build/treb-base-types/src/render_text.js.map +1 -0
- package/build/treb-base-types/src/style.d.ts +214 -0
- package/build/treb-base-types/src/style.js +373 -0
- package/build/treb-base-types/src/style.js.map +1 -0
- package/build/treb-base-types/src/table.d.ts +58 -0
- package/build/treb-base-types/src/table.js +27 -0
- package/build/treb-base-types/src/table.js.map +1 -0
- package/build/treb-base-types/src/text_part.d.ts +26 -0
- package/build/treb-base-types/src/text_part.js +47 -0
- package/build/treb-base-types/src/text_part.js.map +1 -0
- package/build/treb-base-types/src/theme.d.ts +120 -0
- package/build/treb-base-types/src/theme.js +460 -0
- package/build/treb-base-types/src/theme.js.map +1 -0
- package/build/treb-base-types/src/union.d.ts +73 -0
- package/build/treb-base-types/src/union.js +61 -0
- package/build/treb-base-types/src/union.js.map +1 -0
- package/build/treb-base-types/src/value-type.d.ts +86 -0
- package/build/treb-base-types/src/value-type.js +168 -0
- package/build/treb-base-types/src/value-type.js.map +1 -0
- package/build/treb-base-types/src/worker-proxy.d.ts +95 -0
- package/build/treb-base-types/src/worker-proxy.js +221 -0
- package/build/treb-base-types/src/worker-proxy.js.map +1 -0
- package/build/treb-calculator/src/calculator.d.ts +249 -0
- package/build/treb-calculator/src/calculator.js +2755 -0
- package/build/treb-calculator/src/calculator.js.map +1 -0
- package/build/treb-calculator/src/complex-math.d.ts +75 -0
- package/build/treb-calculator/src/complex-math.js +559 -0
- package/build/treb-calculator/src/complex-math.js.map +1 -0
- package/build/treb-calculator/src/dag/array-vertex.d.ts +71 -0
- package/build/treb-calculator/src/dag/array-vertex.js +156 -0
- package/build/treb-calculator/src/dag/array-vertex.js.map +1 -0
- package/build/treb-calculator/src/dag/calculation_leaf_vertex.d.ts +48 -0
- package/build/treb-calculator/src/dag/calculation_leaf_vertex.js +84 -0
- package/build/treb-calculator/src/dag/calculation_leaf_vertex.js.map +1 -0
- package/build/treb-calculator/src/dag/graph.d.ts +134 -0
- package/build/treb-calculator/src/dag/graph.js +842 -0
- package/build/treb-calculator/src/dag/graph.js.map +1 -0
- package/build/treb-calculator/src/dag/spreadsheet_vertex.d.ts +58 -0
- package/build/treb-calculator/src/dag/spreadsheet_vertex.js +232 -0
- package/build/treb-calculator/src/dag/spreadsheet_vertex.js.map +1 -0
- package/build/treb-calculator/src/dag/spreadsheet_vertex_base.d.ts +20 -0
- package/build/treb-calculator/src/dag/spreadsheet_vertex_base.js +25 -0
- package/build/treb-calculator/src/dag/spreadsheet_vertex_base.js.map +1 -0
- package/build/treb-calculator/src/dag/state_leaf_vertex.d.ts +43 -0
- package/build/treb-calculator/src/dag/state_leaf_vertex.js +81 -0
- package/build/treb-calculator/src/dag/state_leaf_vertex.js.map +1 -0
- package/build/treb-calculator/src/dag/vertex.d.ts +71 -0
- package/build/treb-calculator/src/dag/vertex.js +274 -0
- package/build/treb-calculator/src/dag/vertex.js.map +1 -0
- package/build/treb-calculator/src/descriptors.d.ts +189 -0
- package/build/treb-calculator/src/descriptors.js +22 -0
- package/build/treb-calculator/src/descriptors.js.map +1 -0
- package/build/treb-calculator/src/expression-calculator.d.ts +127 -0
- package/build/treb-calculator/src/expression-calculator.js +1033 -0
- package/build/treb-calculator/src/expression-calculator.js.map +1 -0
- package/build/treb-calculator/src/function-error.d.ts +35 -0
- package/build/treb-calculator/src/function-error.js +85 -0
- package/build/treb-calculator/src/function-error.js.map +1 -0
- package/build/treb-calculator/src/function-library.d.ts +22 -0
- package/build/treb-calculator/src/function-library.js +96 -0
- package/build/treb-calculator/src/function-library.js.map +1 -0
- package/build/treb-calculator/src/functions/base-functions.d.ts +7 -0
- package/build/treb-calculator/src/functions/base-functions.js +2611 -0
- package/build/treb-calculator/src/functions/base-functions.js.map +1 -0
- package/build/treb-calculator/src/functions/beta.d.ts +17 -0
- package/build/treb-calculator/src/functions/beta.js +201 -0
- package/build/treb-calculator/src/functions/beta.js.map +1 -0
- package/build/treb-calculator/src/functions/checkbox.d.ts +3 -0
- package/build/treb-calculator/src/functions/checkbox.js +128 -0
- package/build/treb-calculator/src/functions/checkbox.js.map +1 -0
- package/build/treb-calculator/src/functions/complex-functions.d.ts +2 -0
- package/build/treb-calculator/src/functions/complex-functions.js +217 -0
- package/build/treb-calculator/src/functions/complex-functions.js.map +1 -0
- package/build/treb-calculator/src/functions/date-utils.d.ts +3 -0
- package/build/treb-calculator/src/functions/date-utils.js +59 -0
- package/build/treb-calculator/src/functions/date-utils.js.map +1 -0
- package/build/treb-calculator/src/functions/finance-functions.d.ts +2 -0
- package/build/treb-calculator/src/functions/finance-functions.js +547 -0
- package/build/treb-calculator/src/functions/finance-functions.js.map +1 -0
- package/build/treb-calculator/src/functions/fp.d.ts +2 -0
- package/build/treb-calculator/src/functions/fp.js +463 -0
- package/build/treb-calculator/src/functions/fp.js.map +1 -0
- package/build/treb-calculator/src/functions/function-utilities.d.ts +2 -0
- package/build/treb-calculator/src/functions/function-utilities.js +36 -0
- package/build/treb-calculator/src/functions/function-utilities.js.map +1 -0
- package/build/treb-calculator/src/functions/gamma.d.ts +20 -0
- package/build/treb-calculator/src/functions/gamma.js +142 -0
- package/build/treb-calculator/src/functions/gamma.js.map +1 -0
- package/build/treb-calculator/src/functions/information-functions.d.ts +2 -0
- package/build/treb-calculator/src/functions/information-functions.js +71 -0
- package/build/treb-calculator/src/functions/information-functions.js.map +1 -0
- package/build/treb-calculator/src/functions/lambda-functions.d.ts +2 -0
- package/build/treb-calculator/src/functions/lambda-functions.js +85 -0
- package/build/treb-calculator/src/functions/lambda-functions.js.map +1 -0
- package/build/treb-calculator/src/functions/matrix-functions.d.ts +2 -0
- package/build/treb-calculator/src/functions/matrix-functions.js +144 -0
- package/build/treb-calculator/src/functions/matrix-functions.js.map +1 -0
- package/build/treb-calculator/src/functions/normal.d.ts +2 -0
- package/build/treb-calculator/src/functions/normal.js +32 -0
- package/build/treb-calculator/src/functions/normal.js.map +1 -0
- package/build/treb-calculator/src/functions/regex-functions.d.ts +2 -0
- package/build/treb-calculator/src/functions/regex-functions.js +188 -0
- package/build/treb-calculator/src/functions/regex-functions.js.map +1 -0
- package/build/treb-calculator/src/functions/sparkline.d.ts +37 -0
- package/build/treb-calculator/src/functions/sparkline.js +264 -0
- package/build/treb-calculator/src/functions/sparkline.js.map +1 -0
- package/build/treb-calculator/src/functions/statistics-functions.d.ts +6 -0
- package/build/treb-calculator/src/functions/statistics-functions.js +989 -0
- package/build/treb-calculator/src/functions/statistics-functions.js.map +1 -0
- package/build/treb-calculator/src/functions/students-t.d.ts +3 -0
- package/build/treb-calculator/src/functions/students-t.js +64 -0
- package/build/treb-calculator/src/functions/students-t.js.map +1 -0
- package/build/treb-calculator/src/functions/text-functions.d.ts +3 -0
- package/build/treb-calculator/src/functions/text-functions.js +320 -0
- package/build/treb-calculator/src/functions/text-functions.js.map +1 -0
- package/build/treb-calculator/src/index.d.ts +2 -0
- package/build/treb-calculator/src/index.js +22 -0
- package/build/treb-calculator/src/index.js.map +1 -0
- package/build/treb-calculator/src/notifier-types.d.ts +26 -0
- package/build/treb-calculator/src/notifier-types.js +22 -0
- package/build/treb-calculator/src/notifier-types.js.map +1 -0
- package/build/treb-calculator/src/primitives.d.ts +15 -0
- package/build/treb-calculator/src/primitives.js +398 -0
- package/build/treb-calculator/src/primitives.js.map +1 -0
- package/build/treb-calculator/src/utilities.d.ts +68 -0
- package/build/treb-calculator/src/utilities.js +324 -0
- package/build/treb-calculator/src/utilities.js.map +1 -0
- package/build/treb-charts/src/chart-functions.d.ts +8 -0
- package/build/treb-charts/src/chart-functions.js +209 -0
- package/build/treb-charts/src/chart-functions.js.map +1 -0
- package/build/treb-charts/src/chart-types.d.ts +233 -0
- package/build/treb-charts/src/chart-types.js +57 -0
- package/build/treb-charts/src/chart-types.js.map +1 -0
- package/build/treb-charts/src/chart-utils.d.ts +106 -0
- package/build/treb-charts/src/chart-utils.js +1060 -0
- package/build/treb-charts/src/chart-utils.js.map +1 -0
- package/build/treb-charts/src/chart.d.ts +23 -0
- package/build/treb-charts/src/chart.js +94 -0
- package/build/treb-charts/src/chart.js.map +1 -0
- package/build/treb-charts/src/default-chart-renderer.d.ts +16 -0
- package/build/treb-charts/src/default-chart-renderer.js +533 -0
- package/build/treb-charts/src/default-chart-renderer.js.map +1 -0
- package/build/treb-charts/src/index.d.ts +5 -0
- package/build/treb-charts/src/index.js +24 -0
- package/build/treb-charts/src/index.js.map +1 -0
- package/build/treb-charts/src/main.d.ts +1 -0
- package/build/treb-charts/src/main.js +34 -0
- package/build/treb-charts/src/main.js.map +1 -0
- package/build/treb-charts/src/quicksort.d.ts +1 -0
- package/build/treb-charts/src/quicksort.js +49 -0
- package/build/treb-charts/src/quicksort.js.map +1 -0
- package/build/treb-charts/src/rectangle.d.ts +18 -0
- package/build/treb-charts/src/rectangle.js +41 -0
- package/build/treb-charts/src/rectangle.js.map +1 -0
- package/build/treb-charts/src/renderer-type.d.ts +24 -0
- package/build/treb-charts/src/renderer-type.js +22 -0
- package/build/treb-charts/src/renderer-type.js.map +1 -0
- package/build/treb-charts/src/renderer.d.ts +127 -0
- package/build/treb-charts/src/renderer.js +1518 -0
- package/build/treb-charts/src/renderer.js.map +1 -0
- package/build/treb-charts/src/util.d.ts +18 -0
- package/build/treb-charts/src/util.js +71 -0
- package/build/treb-charts/src/util.js.map +1 -0
- package/build/treb-data-model/src/annotation.d.ts +167 -0
- package/build/treb-data-model/src/annotation.js +120 -0
- package/build/treb-data-model/src/annotation.js.map +1 -0
- package/build/treb-data-model/src/conditional_format.d.ts +155 -0
- package/build/treb-data-model/src/conditional_format.js +62 -0
- package/build/treb-data-model/src/conditional_format.js.map +1 -0
- package/build/treb-data-model/src/data-validation.d.ts +28 -0
- package/build/treb-data-model/src/data-validation.js +22 -0
- package/build/treb-data-model/src/data-validation.js.map +1 -0
- package/build/treb-data-model/src/data_model.d.ts +173 -0
- package/build/treb-data-model/src/data_model.js +637 -0
- package/build/treb-data-model/src/data_model.js.map +1 -0
- package/build/treb-data-model/src/index.d.ts +13 -0
- package/build/treb-data-model/src/index.js +28 -0
- package/build/treb-data-model/src/index.js.map +1 -0
- package/build/treb-data-model/src/language-model.d.ts +22 -0
- package/build/treb-data-model/src/language-model.js +22 -0
- package/build/treb-data-model/src/language-model.js.map +1 -0
- package/build/treb-data-model/src/named.d.ts +124 -0
- package/build/treb-data-model/src/named.js +372 -0
- package/build/treb-data-model/src/named.js.map +1 -0
- package/build/treb-data-model/src/serialize_options.d.ts +49 -0
- package/build/treb-data-model/src/serialize_options.js +22 -0
- package/build/treb-data-model/src/serialize_options.js.map +1 -0
- package/build/treb-data-model/src/sheet.d.ts +499 -0
- package/build/treb-data-model/src/sheet.js +2904 -0
- package/build/treb-data-model/src/sheet.js.map +1 -0
- package/build/treb-data-model/src/sheet_collection.d.ts +58 -0
- package/build/treb-data-model/src/sheet_collection.js +112 -0
- package/build/treb-data-model/src/sheet_collection.js.map +1 -0
- package/build/treb-data-model/src/sheet_selection.d.ts +42 -0
- package/build/treb-data-model/src/sheet_selection.js +39 -0
- package/build/treb-data-model/src/sheet_selection.js.map +1 -0
- package/build/treb-data-model/src/sheet_types.d.ts +104 -0
- package/build/treb-data-model/src/sheet_types.js +22 -0
- package/build/treb-data-model/src/sheet_types.js.map +1 -0
- package/build/treb-data-model/src/types.d.ts +59 -0
- package/build/treb-data-model/src/types.js +22 -0
- package/build/treb-data-model/src/types.js.map +1 -0
- package/build/treb-embed/src/custom-element/spreadsheet-constructor.d.ts +75 -0
- package/build/treb-embed/src/custom-element/spreadsheet-constructor.js +1144 -0
- package/build/treb-embed/src/custom-element/spreadsheet-constructor.js.map +1 -0
- package/build/treb-embed/src/custom-element/treb-global.d.ts +36 -0
- package/build/treb-embed/src/custom-element/treb-global.js +64 -0
- package/build/treb-embed/src/custom-element/treb-global.js.map +1 -0
- package/build/treb-embed/src/custom-element/treb-spreadsheet-element.d.ts +1 -0
- package/build/treb-embed/src/custom-element/treb-spreadsheet-element.js +61 -0
- package/build/treb-embed/src/custom-element/treb-spreadsheet-element.js.map +1 -0
- package/build/treb-embed/src/embedded-spreadsheet.d.ts +1358 -0
- package/build/treb-embed/src/embedded-spreadsheet.js +5205 -0
- package/build/treb-embed/src/embedded-spreadsheet.js.map +1 -0
- package/build/treb-embed/src/index.d.ts +12 -0
- package/build/treb-embed/src/index.js +34 -0
- package/build/treb-embed/src/index.js.map +1 -0
- package/build/treb-embed/src/options.d.ts +266 -0
- package/build/treb-embed/src/options.js +56 -0
- package/build/treb-embed/src/options.js.map +1 -0
- package/build/treb-embed/src/plugin.d.ts +9 -0
- package/build/treb-embed/src/plugin.js +22 -0
- package/build/treb-embed/src/plugin.js.map +1 -0
- package/build/treb-embed/src/progress-dialog.d.ts +49 -0
- package/build/treb-embed/src/progress-dialog.js +178 -0
- package/build/treb-embed/src/progress-dialog.js.map +1 -0
- package/build/treb-embed/src/selection-state.d.ts +15 -0
- package/build/treb-embed/src/selection-state.js +22 -0
- package/build/treb-embed/src/selection-state.js.map +1 -0
- package/build/treb-embed/src/spinner.d.ts +8 -0
- package/build/treb-embed/src/spinner.js +40 -0
- package/build/treb-embed/src/spinner.js.map +1 -0
- package/build/treb-embed/src/toolbar-message.d.ts +72 -0
- package/build/treb-embed/src/toolbar-message.js +22 -0
- package/build/treb-embed/src/toolbar-message.js.map +1 -0
- package/build/treb-embed/src/types.d.ts +185 -0
- package/build/treb-embed/src/types.js +45 -0
- package/build/treb-embed/src/types.js.map +1 -0
- package/build/treb-embed/tsconfig.tsbuildinfo +1 -0
- package/build/treb-export/src/address-type.d.ts +34 -0
- package/build/treb-export/src/address-type.js +53 -0
- package/build/treb-export/src/address-type.js.map +1 -0
- package/build/treb-export/src/base-template.d.ts +1 -0
- package/build/treb-export/src/base-template.js +22 -0
- package/build/treb-export/src/base-template.js.map +1 -0
- package/build/treb-export/src/column-width.d.ts +2 -0
- package/build/treb-export/src/column-width.js +80 -0
- package/build/treb-export/src/column-width.js.map +1 -0
- package/build/treb-export/src/drawing/bubble-chart-template.d.ts +514 -0
- package/build/treb-export/src/drawing/bubble-chart-template.js +544 -0
- package/build/treb-export/src/drawing/bubble-chart-template.js.map +1 -0
- package/build/treb-export/src/drawing/chart-template-components2.d.ts +365 -0
- package/build/treb-export/src/drawing/chart-template-components2.js +386 -0
- package/build/treb-export/src/drawing/chart-template-components2.js.map +1 -0
- package/build/treb-export/src/drawing/chart.d.ts +26 -0
- package/build/treb-export/src/drawing/chart.js +247 -0
- package/build/treb-export/src/drawing/chart.js.map +1 -0
- package/build/treb-export/src/drawing/column-chart-template2.d.ts +490 -0
- package/build/treb-export/src/drawing/column-chart-template2.js +518 -0
- package/build/treb-export/src/drawing/column-chart-template2.js.map +1 -0
- package/build/treb-export/src/drawing/donut-chart-template2.d.ts +272 -0
- package/build/treb-export/src/drawing/donut-chart-template2.js +293 -0
- package/build/treb-export/src/drawing/donut-chart-template2.js.map +1 -0
- package/build/treb-export/src/drawing/drawing.d.ts +49 -0
- package/build/treb-export/src/drawing/drawing.js +193 -0
- package/build/treb-export/src/drawing/drawing.js.map +1 -0
- package/build/treb-export/src/drawing/embedded-image.d.ts +12 -0
- package/build/treb-export/src/drawing/embedded-image.js +54 -0
- package/build/treb-export/src/drawing/embedded-image.js.map +1 -0
- package/build/treb-export/src/drawing/scatter-chart-template2.d.ts +520 -0
- package/build/treb-export/src/drawing/scatter-chart-template2.js +551 -0
- package/build/treb-export/src/drawing/scatter-chart-template2.js.map +1 -0
- package/build/treb-export/src/export.d.ts +72 -0
- package/build/treb-export/src/export.js +2039 -0
- package/build/treb-export/src/export.js.map +1 -0
- package/build/treb-export/src/import-export-messages.d.ts +31 -0
- package/build/treb-export/src/import-export-messages.js +22 -0
- package/build/treb-export/src/import-export-messages.js.map +1 -0
- package/build/treb-export/src/import.d.ts +33 -0
- package/build/treb-export/src/import.js +1258 -0
- package/build/treb-export/src/import.js.map +1 -0
- package/build/treb-export/src/index.worker.d.ts +1 -0
- package/build/treb-export/src/index.worker.js +93 -0
- package/build/treb-export/src/index.worker.js.map +1 -0
- package/build/treb-export/src/metadata.d.ts +51 -0
- package/build/treb-export/src/metadata.js +153 -0
- package/build/treb-export/src/metadata.js.map +1 -0
- package/build/treb-export/src/ooxml.d.ts +7 -0
- package/build/treb-export/src/ooxml.js +41 -0
- package/build/treb-export/src/ooxml.js.map +1 -0
- package/build/treb-export/src/relationship.d.ts +8 -0
- package/build/treb-export/src/relationship.js +27 -0
- package/build/treb-export/src/relationship.js.map +1 -0
- package/build/treb-export/src/shared-strings.d.ts +11 -0
- package/build/treb-export/src/shared-strings.js +105 -0
- package/build/treb-export/src/shared-strings.js.map +1 -0
- package/build/treb-export/src/template-2.d.ts +1 -0
- package/build/treb-export/src/template-2.js +22 -0
- package/build/treb-export/src/template-2.js.map +1 -0
- package/build/treb-export/src/unescape_xml.d.ts +1 -0
- package/build/treb-export/src/unescape_xml.js +61 -0
- package/build/treb-export/src/unescape_xml.js.map +1 -0
- package/build/treb-export/src/workbook-sheet.d.ts +75 -0
- package/build/treb-export/src/workbook-sheet.js +128 -0
- package/build/treb-export/src/workbook-sheet.js.map +1 -0
- package/build/treb-export/src/workbook-style.d.ts +110 -0
- package/build/treb-export/src/workbook-style.js +1134 -0
- package/build/treb-export/src/workbook-style.js.map +1 -0
- package/build/treb-export/src/workbook-theme.d.ts +13 -0
- package/build/treb-export/src/workbook-theme.js +85 -0
- package/build/treb-export/src/workbook-theme.js.map +1 -0
- package/build/treb-export/src/workbook.d.ts +123 -0
- package/build/treb-export/src/workbook.js +644 -0
- package/build/treb-export/src/workbook.js.map +1 -0
- package/build/treb-export/src/xml-test.d.ts +9 -0
- package/build/treb-export/src/xml-test.js +52 -0
- package/build/treb-export/src/xml-test.js.map +1 -0
- package/build/treb-export/src/xml-utils.d.ts +76 -0
- package/build/treb-export/src/xml-utils.js +223 -0
- package/build/treb-export/src/xml-utils.js.map +1 -0
- package/build/treb-export/src/zip-wrapper.d.ts +22 -0
- package/build/treb-export/src/zip-wrapper.js +93 -0
- package/build/treb-export/src/zip-wrapper.js.map +1 -0
- package/build/treb-format/src/format.d.ts +130 -0
- package/build/treb-format/src/format.js +805 -0
- package/build/treb-format/src/format.js.map +1 -0
- package/build/treb-format/src/format_cache.d.ts +55 -0
- package/build/treb-format/src/format_cache.js +166 -0
- package/build/treb-format/src/format_cache.js.map +1 -0
- package/build/treb-format/src/format_parser.d.ts +70 -0
- package/build/treb-format/src/format_parser.js +618 -0
- package/build/treb-format/src/format_parser.js.map +1 -0
- package/build/treb-format/src/index.d.ts +4 -0
- package/build/treb-format/src/index.js +25 -0
- package/build/treb-format/src/index.js.map +1 -0
- package/build/treb-format/src/number_format_section.d.ts +58 -0
- package/build/treb-format/src/number_format_section.js +78 -0
- package/build/treb-format/src/number_format_section.js.map +1 -0
- package/build/treb-format/src/value_parser.d.ts +48 -0
- package/build/treb-format/src/value_parser.js +244 -0
- package/build/treb-format/src/value_parser.js.map +1 -0
- package/build/treb-grid/src/editors/autocomplete.d.ts +39 -0
- package/build/treb-grid/src/editors/autocomplete.js +316 -0
- package/build/treb-grid/src/editors/autocomplete.js.map +1 -0
- package/build/treb-grid/src/editors/autocomplete_matcher.d.ts +74 -0
- package/build/treb-grid/src/editors/autocomplete_matcher.js +212 -0
- package/build/treb-grid/src/editors/autocomplete_matcher.js.map +1 -0
- package/build/treb-grid/src/editors/editor.d.ts +214 -0
- package/build/treb-grid/src/editors/editor.js +879 -0
- package/build/treb-grid/src/editors/editor.js.map +1 -0
- package/build/treb-grid/src/editors/external_editor.d.ts +11 -0
- package/build/treb-grid/src/editors/external_editor.js +118 -0
- package/build/treb-grid/src/editors/external_editor.js.map +1 -0
- package/build/treb-grid/src/editors/formula_bar.d.ts +85 -0
- package/build/treb-grid/src/editors/formula_bar.js +444 -0
- package/build/treb-grid/src/editors/formula_bar.js.map +1 -0
- package/build/treb-grid/src/editors/overlay_editor.d.ts +85 -0
- package/build/treb-grid/src/editors/overlay_editor.js +353 -0
- package/build/treb-grid/src/editors/overlay_editor.js.map +1 -0
- package/build/treb-grid/src/index.d.ts +12 -0
- package/build/treb-grid/src/index.js +28 -0
- package/build/treb-grid/src/index.js.map +1 -0
- package/build/treb-grid/src/layout/base_layout.d.ts +346 -0
- package/build/treb-grid/src/layout/base_layout.js +2050 -0
- package/build/treb-grid/src/layout/base_layout.js.map +1 -0
- package/build/treb-grid/src/layout/grid_layout.d.ts +19 -0
- package/build/treb-grid/src/layout/grid_layout.js +235 -0
- package/build/treb-grid/src/layout/grid_layout.js.map +1 -0
- package/build/treb-grid/src/layout/mock-layout.d.ts +10 -0
- package/build/treb-grid/src/layout/mock-layout.js +37 -0
- package/build/treb-grid/src/layout/mock-layout.js.map +1 -0
- package/build/treb-grid/src/render/selection-renderer.d.ts +97 -0
- package/build/treb-grid/src/render/selection-renderer.js +315 -0
- package/build/treb-grid/src/render/selection-renderer.js.map +1 -0
- package/build/treb-grid/src/render/svg_header_overlay.d.ts +20 -0
- package/build/treb-grid/src/render/svg_header_overlay.js +76 -0
- package/build/treb-grid/src/render/svg_header_overlay.js.map +1 -0
- package/build/treb-grid/src/render/svg_selection_block.d.ts +27 -0
- package/build/treb-grid/src/render/svg_selection_block.js +106 -0
- package/build/treb-grid/src/render/svg_selection_block.js.map +1 -0
- package/build/treb-grid/src/render/tile_renderer.d.ts +121 -0
- package/build/treb-grid/src/render/tile_renderer.js +1609 -0
- package/build/treb-grid/src/render/tile_renderer.js.map +1 -0
- package/build/treb-grid/src/types/border_constants.d.ts +9 -0
- package/build/treb-grid/src/types/border_constants.js +34 -0
- package/build/treb-grid/src/types/border_constants.js.map +1 -0
- package/build/treb-grid/src/types/clipboard_data.d.ts +11 -0
- package/build/treb-grid/src/types/clipboard_data.js +22 -0
- package/build/treb-grid/src/types/clipboard_data.js.map +1 -0
- package/build/treb-grid/src/types/clipboard_data2.d.ts +46 -0
- package/build/treb-grid/src/types/clipboard_data2.js +22 -0
- package/build/treb-grid/src/types/clipboard_data2.js.map +1 -0
- package/build/treb-grid/src/types/drag_mask.d.ts +10 -0
- package/build/treb-grid/src/types/drag_mask.js +78 -0
- package/build/treb-grid/src/types/drag_mask.js.map +1 -0
- package/build/treb-grid/src/types/external_editor_config.d.ts +33 -0
- package/build/treb-grid/src/types/external_editor_config.js +22 -0
- package/build/treb-grid/src/types/external_editor_config.js.map +1 -0
- package/build/treb-grid/src/types/grid.d.ts +806 -0
- package/build/treb-grid/src/types/grid.js +6410 -0
- package/build/treb-grid/src/types/grid.js.map +1 -0
- package/build/treb-grid/src/types/grid_base.d.ts +442 -0
- package/build/treb-grid/src/types/grid_base.js +3523 -0
- package/build/treb-grid/src/types/grid_base.js.map +1 -0
- package/build/treb-grid/src/types/grid_command.d.ts +408 -0
- package/build/treb-grid/src/types/grid_command.js +75 -0
- package/build/treb-grid/src/types/grid_command.js.map +1 -0
- package/build/treb-grid/src/types/grid_events.d.ts +93 -0
- package/build/treb-grid/src/types/grid_events.js +36 -0
- package/build/treb-grid/src/types/grid_events.js.map +1 -0
- package/build/treb-grid/src/types/grid_options.d.ts +50 -0
- package/build/treb-grid/src/types/grid_options.js +34 -0
- package/build/treb-grid/src/types/grid_options.js.map +1 -0
- package/build/treb-grid/src/types/scale-control.d.ts +21 -0
- package/build/treb-grid/src/types/scale-control.js +148 -0
- package/build/treb-grid/src/types/scale-control.js.map +1 -0
- package/build/treb-grid/src/types/set_range_options.d.ts +24 -0
- package/build/treb-grid/src/types/set_range_options.js +22 -0
- package/build/treb-grid/src/types/set_range_options.js.map +1 -0
- package/build/treb-grid/src/types/tab_bar.d.ts +84 -0
- package/build/treb-grid/src/types/tab_bar.js +426 -0
- package/build/treb-grid/src/types/tab_bar.js.map +1 -0
- package/build/treb-grid/src/types/tile.d.ts +29 -0
- package/build/treb-grid/src/types/tile.js +22 -0
- package/build/treb-grid/src/types/tile.js.map +1 -0
- package/build/treb-grid/src/types/update_flags.d.ts +48 -0
- package/build/treb-grid/src/types/update_flags.js +22 -0
- package/build/treb-grid/src/types/update_flags.js.map +1 -0
- package/build/treb-grid/src/util/fontmetrics.d.ts +21 -0
- package/build/treb-grid/src/util/fontmetrics.js +82 -0
- package/build/treb-grid/src/util/fontmetrics.js.map +1 -0
- package/build/treb-grid/src/util/ua.d.ts +33 -0
- package/build/treb-grid/src/util/ua.js +86 -0
- package/build/treb-grid/src/util/ua.js.map +1 -0
- package/build/treb-parser/src/csv-parser.d.ts +13 -0
- package/build/treb-parser/src/csv-parser.js +107 -0
- package/build/treb-parser/src/csv-parser.js.map +1 -0
- package/build/treb-parser/src/index.d.ts +4 -0
- package/build/treb-parser/src/index.js +25 -0
- package/build/treb-parser/src/index.js.map +1 -0
- package/build/treb-parser/src/md-parser.d.ts +97 -0
- package/build/treb-parser/src/md-parser.js +403 -0
- package/build/treb-parser/src/md-parser.js.map +1 -0
- package/build/treb-parser/src/parser-types.d.ts +345 -0
- package/build/treb-parser/src/parser-types.js +53 -0
- package/build/treb-parser/src/parser-types.js.map +1 -0
- package/build/treb-parser/src/parser.d.ts +422 -0
- package/build/treb-parser/src/parser.js +2418 -0
- package/build/treb-parser/src/parser.js.map +1 -0
- package/build/treb-utils/src/event_source.d.ts +34 -0
- package/build/treb-utils/src/event_source.js +110 -0
- package/build/treb-utils/src/event_source.js.map +1 -0
- package/build/treb-utils/src/ievent_source.d.ts +9 -0
- package/build/treb-utils/src/ievent_source.js +22 -0
- package/build/treb-utils/src/ievent_source.js.map +1 -0
- package/build/treb-utils/src/index.d.ts +6 -0
- package/build/treb-utils/src/index.js +30 -0
- package/build/treb-utils/src/index.js.map +1 -0
- package/build/treb-utils/src/measurement.d.ts +42 -0
- package/build/treb-utils/src/measurement.js +145 -0
- package/build/treb-utils/src/measurement.js.map +1 -0
- package/build/treb-utils/src/scale.d.ts +16 -0
- package/build/treb-utils/src/scale.js +106 -0
- package/build/treb-utils/src/scale.js.map +1 -0
- package/build/treb-utils/src/serialize_html.d.ts +5 -0
- package/build/treb-utils/src/serialize_html.js +128 -0
- package/build/treb-utils/src/serialize_html.js.map +1 -0
- package/build/treb-utils/src/validate_uri.d.ts +20 -0
- package/build/treb-utils/src/validate_uri.js +55 -0
- package/build/treb-utils/src/validate_uri.js.map +1 -0
- package/dist/{chunk-Z4XFMZ2X.mjs → chunk-E35ONJUS.mjs} +1 -1
- package/dist/treb-export-worker.mjs +2 -2
- package/dist/treb-spreadsheet.mjs +4 -4
- package/dist/treb.d.ts +1 -1
- package/esbuild-composite.mjs +5 -1
- package/package.json +67 -3
- package/treb-embed/src/custom-element/spreadsheet-constructor.ts +7 -3
- package/treb-embed/src/embedded-spreadsheet.ts +1 -1
- package/treb-grid/src/types/grid_options.ts +1 -1
- package/tsproject.json +1 -2
- package/dist/chunk-43DLP2OX.mjs +0 -11
- package/dist/chunk-4CKS56PE.mjs +0 -11
- package/dist/chunk-75PARUQE.mjs +0 -11
- package/dist/chunk-7QD63AZS.mjs +0 -24601
- package/dist/chunk-A55ARVRD.mjs +0 -11
- package/dist/chunk-DESAKYW4.mjs +0 -11
- package/dist/chunk-EQ2R5W6P.mjs +0 -24565
- package/dist/chunk-IYJU2J6D.mjs +0 -24601
- package/dist/chunk-KSJFPGXT.mjs +0 -11
- package/dist/chunk-MQK4DNXI.mjs +0 -11
- package/dist/chunk-ORQFKLXM.mjs +0 -24601
- package/dist/chunk-SFDNNDHY.mjs +0 -11
- package/dist/chunk-T47DX5MI.mjs +0 -11
- package/dist/chunk-T6ILBVEX.mjs +0 -11
- package/dist/chunk-TPRCDYYG.mjs +0 -11
- package/dist/chunk-YAHNOOHO.mjs +0 -11
- package/dist/chunk-YLCFKX2G.mjs +0 -24601
|
@@ -0,0 +1,879 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of TREB.
|
|
3
|
+
*
|
|
4
|
+
* TREB is free software: you can redistribute it and/or modify it under the
|
|
5
|
+
* terms of the GNU General Public License as published by the Free Software
|
|
6
|
+
* Foundation, either version 3 of the License, or (at your option) any
|
|
7
|
+
* later version.
|
|
8
|
+
*
|
|
9
|
+
* TREB is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
10
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
11
|
+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
12
|
+
* details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU General Public License along
|
|
15
|
+
* with TREB. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*
|
|
17
|
+
* Copyright 2022-2026 trebco, llc.
|
|
18
|
+
* info@treb.app
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* attempting (at least partial) rewrite of editor. better support of
|
|
23
|
+
* external editors, and a little cleaner behavior for context highlighting.
|
|
24
|
+
*
|
|
25
|
+
* I didn't want to handle spellcheck, but we're setting a flag reflecting
|
|
26
|
+
* whether it's a formula; so we probably should do it.
|
|
27
|
+
*
|
|
28
|
+
* we are specifically NOT handling the following:
|
|
29
|
+
*
|
|
30
|
+
* - enter key
|
|
31
|
+
*
|
|
32
|
+
* subclasses or callers can handle those.
|
|
33
|
+
*
|
|
34
|
+
* ---
|
|
35
|
+
*
|
|
36
|
+
* NOTE: external editors might run in a different realm (in the js meaning
|
|
37
|
+
* of that term). so we don't necessarily want to use the spreadsheet's context
|
|
38
|
+
* for everything. this is going to be extremely confusing.
|
|
39
|
+
*
|
|
40
|
+
*/
|
|
41
|
+
import { Area, IsCellAddress, Localization, Rectangle, DOMContext } from 'treb-base-types';
|
|
42
|
+
import { Parser } from 'treb-parser';
|
|
43
|
+
import { EventSource } from 'treb-utils';
|
|
44
|
+
import { AutocompleteMatcher } from './autocomplete_matcher';
|
|
45
|
+
export class Editor extends EventSource {
|
|
46
|
+
model;
|
|
47
|
+
view;
|
|
48
|
+
autocomplete;
|
|
49
|
+
static FormulaChars = ('$^&*(-+={[<>/~%@' + Localization.argument_separator).split(''); // FIXME: i18n
|
|
50
|
+
/**
|
|
51
|
+
* the current edit cell. in the event we're editing a merged or
|
|
52
|
+
* array cell, this might be different than the actual target address.
|
|
53
|
+
*/
|
|
54
|
+
active_cell;
|
|
55
|
+
/** matcher. passed in by owner. should move to constructor arguments */
|
|
56
|
+
autocomplete_matcher;
|
|
57
|
+
/** the containing node, used for layout */
|
|
58
|
+
container_node;
|
|
59
|
+
/**
|
|
60
|
+
* this is the node we are currently editing. it's possible we are not
|
|
61
|
+
* editing any cell, but just formatting. this one sends events and is
|
|
62
|
+
* the target for inserting addresses.
|
|
63
|
+
*/
|
|
64
|
+
active_editor;
|
|
65
|
+
/**
|
|
66
|
+
* all nodes that are involved with this editor. we format all of them,
|
|
67
|
+
* and if you edit one we might switch the colors in the others as
|
|
68
|
+
* references change.
|
|
69
|
+
*/
|
|
70
|
+
nodes = [];
|
|
71
|
+
/**
|
|
72
|
+
* address of cell we're editing, if we're editing a cell
|
|
73
|
+
*/
|
|
74
|
+
target_address;
|
|
75
|
+
/**
|
|
76
|
+
* assume we're editing a formula. this is for the external editor.
|
|
77
|
+
* if we switch the formula bar to inherit from this class, it should
|
|
78
|
+
* be false.
|
|
79
|
+
*/
|
|
80
|
+
assume_formula = false;
|
|
81
|
+
/**
|
|
82
|
+
* this flag indicates we're editing a formula, which starts with `=`.
|
|
83
|
+
*/
|
|
84
|
+
text_formula = false;
|
|
85
|
+
/**
|
|
86
|
+
* this has changed -- we don't have an internal field. instead we'll
|
|
87
|
+
* check when called. it's slightly more expensive but should be
|
|
88
|
+
* relatively rare.
|
|
89
|
+
*/
|
|
90
|
+
get selecting() {
|
|
91
|
+
if (this.assume_formula) {
|
|
92
|
+
return true; // always selecting
|
|
93
|
+
}
|
|
94
|
+
if (!this.text_formula) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
// FIXME: also if you change the selection. our insert routine
|
|
98
|
+
// handles that but this will return false. the test is "is the
|
|
99
|
+
// cursor in or at the end of a reference?"
|
|
100
|
+
if (this.active_editor && this.active_editor.node === this.active_editor.node.ownerDocument.activeElement) {
|
|
101
|
+
const view = this.active_editor.node.ownerDocument.defaultView;
|
|
102
|
+
const selection = view.getSelection();
|
|
103
|
+
const count = selection?.rangeCount;
|
|
104
|
+
if (count) {
|
|
105
|
+
const range = selection?.getRangeAt(0);
|
|
106
|
+
const element = range?.endContainer instanceof view.HTMLElement ? range.endContainer :
|
|
107
|
+
range.endContainer?.parentElement;
|
|
108
|
+
// this is a reference, assume we're selecting (we will replace)
|
|
109
|
+
if (element?.dataset.reference !== undefined) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
// we may be able to use the selection directly
|
|
113
|
+
/*
|
|
114
|
+
if (range?.endContainer instanceof Text) {
|
|
115
|
+
const str = (range.endContainer.textContent?.substring(0, range.endOffset) || '').trim();
|
|
116
|
+
if (str.length && Editor2.FormulaChars.includes(str[str.length - 1])) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
*/
|
|
121
|
+
// start, not end
|
|
122
|
+
if (range?.startContainer instanceof view.Text) {
|
|
123
|
+
const str = (range.startContainer.textContent?.substring(0, range.startOffset) || '').trim();
|
|
124
|
+
if (str.length && Editor.FormulaChars.includes(str[str.length - 1])) {
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
console.info("mark 21", range);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const text = this.SubstringToCaret2(this.active_editor.node)[1].trim();
|
|
133
|
+
if (text.length) {
|
|
134
|
+
const char = text[text.length - 1];
|
|
135
|
+
return Editor.FormulaChars.includes(char);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
/** internal. not sure why we have a shadow property. */
|
|
141
|
+
composite_dependencies = [];
|
|
142
|
+
/** accessor */
|
|
143
|
+
get dependencies() {
|
|
144
|
+
return this.composite_dependencies;
|
|
145
|
+
}
|
|
146
|
+
/** reference to model parser */
|
|
147
|
+
parser;
|
|
148
|
+
constructor(model, view, autocomplete) {
|
|
149
|
+
super();
|
|
150
|
+
this.model = model;
|
|
151
|
+
this.view = view;
|
|
152
|
+
this.autocomplete = autocomplete;
|
|
153
|
+
this.parser = model.parser;
|
|
154
|
+
}
|
|
155
|
+
FocusEditor() {
|
|
156
|
+
if (this.active_editor) {
|
|
157
|
+
this.active_editor.node.focus();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* add an event listener to the node. these are stored so we can remove
|
|
162
|
+
* them later if the node is disconnected.
|
|
163
|
+
*
|
|
164
|
+
* listeners moved to node descriptors so we can have multiple sets.
|
|
165
|
+
*/
|
|
166
|
+
RegisterListener(descriptor, key, handler) {
|
|
167
|
+
descriptor.node.addEventListener(key, handler);
|
|
168
|
+
if (!descriptor.listeners) {
|
|
169
|
+
descriptor.listeners = new Map();
|
|
170
|
+
}
|
|
171
|
+
descriptor.listeners.set(key, handler);
|
|
172
|
+
}
|
|
173
|
+
SelectAll(node) {
|
|
174
|
+
const view = node.ownerDocument.defaultView;
|
|
175
|
+
const selection = view.getSelection();
|
|
176
|
+
const range = node.ownerDocument.createRange();
|
|
177
|
+
range.selectNode(node);
|
|
178
|
+
selection?.removeAllRanges();
|
|
179
|
+
selection?.addRange(range);
|
|
180
|
+
}
|
|
181
|
+
SetCaret(start, end) {
|
|
182
|
+
const doc = start.node.ownerDocument;
|
|
183
|
+
const view = doc?.defaultView;
|
|
184
|
+
const selection = view.getSelection();
|
|
185
|
+
const range = doc?.createRange();
|
|
186
|
+
const FirstTextNode = (node) => {
|
|
187
|
+
let target = node;
|
|
188
|
+
while (target && !(target instanceof view.Text) && !!target.firstChild) {
|
|
189
|
+
target = target.firstChild;
|
|
190
|
+
}
|
|
191
|
+
return target;
|
|
192
|
+
};
|
|
193
|
+
const start_node = FirstTextNode(start.node);
|
|
194
|
+
if (end) {
|
|
195
|
+
const end_node = FirstTextNode(end.node);
|
|
196
|
+
if (selection && range) {
|
|
197
|
+
range.setStart(start_node, start.offset);
|
|
198
|
+
range.setEnd(end_node, end.offset);
|
|
199
|
+
selection.removeAllRanges();
|
|
200
|
+
selection.addRange(range);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
if (selection && range) {
|
|
205
|
+
range.setStart(start_node, start.offset);
|
|
206
|
+
range.setEnd(start_node, start.offset);
|
|
207
|
+
range.collapse(true);
|
|
208
|
+
selection.removeAllRanges();
|
|
209
|
+
selection.addRange(range);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
*
|
|
215
|
+
*/
|
|
216
|
+
InsertReference(reference, toggle_reference_type = false, typed_reference_list = []) {
|
|
217
|
+
if (!this.active_editor) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const view = this.active_editor.node.ownerDocument.defaultView;
|
|
221
|
+
const selection = view.getSelection();
|
|
222
|
+
if (!selection) {
|
|
223
|
+
throw new Error('error getting selection');
|
|
224
|
+
}
|
|
225
|
+
if (selection.rangeCount === 0) {
|
|
226
|
+
// console.warn('range count is 0');
|
|
227
|
+
return '';
|
|
228
|
+
}
|
|
229
|
+
const range = selection.getRangeAt(0);
|
|
230
|
+
const text = this.active_editor.node.textContent || '';
|
|
231
|
+
// so what we are doing here depends on where the caret is.
|
|
232
|
+
// if the caret is in a reference (address, range, &c) then
|
|
233
|
+
// we replace the reference. that seems like the logical thing
|
|
234
|
+
// to do.
|
|
235
|
+
// if the caret is not in a reference, then we need to insert/append
|
|
236
|
+
// it at the caret position. should we replace existing stuff? what
|
|
237
|
+
// if it's in a literal? ...
|
|
238
|
+
// maybe the criteria should be "is there a range selection", and if
|
|
239
|
+
// so, replace the range selection -- otherwise, insert the reference
|
|
240
|
+
// (possibly with a delimeter, space, or operator?)
|
|
241
|
+
// A: easiest case: selection is in a reference. replace it.
|
|
242
|
+
// actually the first case should be the range selection, since that
|
|
243
|
+
// might include _more_ than an existing reference, and we want to
|
|
244
|
+
// replace the entire range selection.
|
|
245
|
+
if (range.startContainer instanceof view.Text) {
|
|
246
|
+
// first case: range selected
|
|
247
|
+
if (!range.collapsed && range.startOffset < range.endOffset) {
|
|
248
|
+
const substrings = this.SubstringToCaret2(this.active_editor.node);
|
|
249
|
+
// console.info("Case 1", substrings);
|
|
250
|
+
/*
|
|
251
|
+
// console.info('case 1');
|
|
252
|
+
|
|
253
|
+
const substring_1 = this.SubstringToCaret(this.editor_node, true);
|
|
254
|
+
const substring_2 = this.SubstringToCaret(this.editor_node, false);
|
|
255
|
+
|
|
256
|
+
const test = this.SubstringToCaret2(this.editor_node);
|
|
257
|
+
console.info(
|
|
258
|
+
(test[0] === substring_1 && test[1] === substring_2) ? 'GOOD' : 'BAD',
|
|
259
|
+
{ test, substring_1, substring_2 });
|
|
260
|
+
*/
|
|
261
|
+
this.active_editor.node.textContent = substrings[0] + reference + text.substring(substrings[1].length);
|
|
262
|
+
this.SetCaret({
|
|
263
|
+
node: this.active_editor.node,
|
|
264
|
+
offset: substrings[0].length,
|
|
265
|
+
}, {
|
|
266
|
+
node: this.active_editor.node,
|
|
267
|
+
offset: substrings[0].length + reference.length
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
// check if we're in a reference node; if so, replace
|
|
272
|
+
const parent = range.startContainer.parentElement;
|
|
273
|
+
if (parent instanceof view.HTMLElement && parent.dataset.reference) {
|
|
274
|
+
if (toggle_reference_type && typed_reference_list.length) {
|
|
275
|
+
for (const [index, ref] of typed_reference_list.entries()) {
|
|
276
|
+
if (ref === parent.textContent) {
|
|
277
|
+
reference = typed_reference_list[index + 1] || typed_reference_list[0];
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
// replace text
|
|
283
|
+
parent.textContent = reference;
|
|
284
|
+
this.SetCaret({
|
|
285
|
+
node: parent,
|
|
286
|
+
offset: reference.length,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
// console.info('case 3;', {sc: range.startContainer, text: range.startContainer.data, parent});
|
|
291
|
+
// otherwise, insert at caret. should we add a delimeter? it
|
|
292
|
+
// probably depends on what's immediately preceding the caret.
|
|
293
|
+
// UPDATE: what about following the caret?
|
|
294
|
+
const substring = this.SubstringToCaret2(this.active_editor.node)[1];
|
|
295
|
+
let leader = '';
|
|
296
|
+
// let trailer = '';
|
|
297
|
+
const trimmed = substring.trim();
|
|
298
|
+
if (trimmed.length) {
|
|
299
|
+
const char = trimmed[trimmed.length - 1];
|
|
300
|
+
if (!Editor.FormulaChars.includes(char)) {
|
|
301
|
+
if (substring.length === trimmed.length) {
|
|
302
|
+
leader = ' +';
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
leader = '+';
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// check after. this is a little different because we still
|
|
310
|
+
// want to set the caret at the end of the original reference.
|
|
311
|
+
// we need a flag.
|
|
312
|
+
// we can't insert a space, because that will break parsing (it
|
|
313
|
+
// will become invalid). I guess we could insert a space, and just
|
|
314
|
+
// accept that, but this seems like it works better (doing nothing).
|
|
315
|
+
/*
|
|
316
|
+
if (text.length > substring.length) {
|
|
317
|
+
const char = text[substring.length];
|
|
318
|
+
if (!Editor2.FormulaChars.includes(char) && !/\s/.test(char)) {
|
|
319
|
+
trailer = ' ';
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
*/
|
|
323
|
+
this.active_editor.node.textContent = substring + leader + reference + text.substring(substring.length);
|
|
324
|
+
this.SetCaret({
|
|
325
|
+
node: this.active_editor.node,
|
|
326
|
+
offset: substring.length + reference.length + leader.length,
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
// if startContainer is not text, that usually means the container
|
|
333
|
+
// is empty. I don't think there's any other case. so we can insert
|
|
334
|
+
// the text. we'll want to create a node, and we'll want to set the
|
|
335
|
+
// cursor at the end.
|
|
336
|
+
if (range.startContainer instanceof view.HTMLElement) {
|
|
337
|
+
range.startContainer.textContent = reference;
|
|
338
|
+
this.SetCaret({
|
|
339
|
+
node: range.startContainer,
|
|
340
|
+
offset: reference.length,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
else {
|
|
344
|
+
console.warn("unexpected range start container", range.startContainer);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
// there may be some cases where we don't need to do this
|
|
348
|
+
this.UpdateText(this.active_editor);
|
|
349
|
+
this.UpdateColors();
|
|
350
|
+
// this does not raise an input event. probably because we're calling
|
|
351
|
+
// it from script. but we might be pretty disconnected from the owner.
|
|
352
|
+
// can we use a synthentic event that matches one of the real ones?
|
|
353
|
+
// A: yes, except that isTrusted will evaluate to false. which I guess
|
|
354
|
+
// is fine, in this context?
|
|
355
|
+
// make sure to do this after updating so we have a current list of
|
|
356
|
+
// references attached to the node
|
|
357
|
+
this.active_editor.node.dispatchEvent(new Event('input', {
|
|
358
|
+
bubbles: true,
|
|
359
|
+
cancelable: true,
|
|
360
|
+
}));
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* this method does three things:
|
|
364
|
+
*
|
|
365
|
+
* (1) builds a flat list of references across all nodes
|
|
366
|
+
* (2) applies colors to formatted references
|
|
367
|
+
* (3) sends an event (if necessary, or forced)
|
|
368
|
+
*
|
|
369
|
+
* that's fine, but it needs a new name.
|
|
370
|
+
*
|
|
371
|
+
*/
|
|
372
|
+
UpdateColors(force_event = false, toll_update = false) {
|
|
373
|
+
// const view = this.active_editor?.node.ownerDocument.defaultView as (Window & typeof globalThis);
|
|
374
|
+
// create a map of canonical label -> area
|
|
375
|
+
const map = new Map();
|
|
376
|
+
// also create a map of label -> index
|
|
377
|
+
const indexes = new Map();
|
|
378
|
+
for (const support of this.nodes) {
|
|
379
|
+
for (const area of support.references || []) {
|
|
380
|
+
const label = this.model.AddressToLabel(area, true);
|
|
381
|
+
if (!map.has(label)) {
|
|
382
|
+
map.set(label, area);
|
|
383
|
+
indexes.set(label, indexes.size);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
// FIXME: compare against current and short-circuit
|
|
388
|
+
// console.info({map, indexes});
|
|
389
|
+
// now apply colors to nodes
|
|
390
|
+
for (const entry of this.nodes) {
|
|
391
|
+
for (const node of Array.from(entry.node.childNodes)) {
|
|
392
|
+
const view = node.ownerDocument?.defaultView;
|
|
393
|
+
if (view && node instanceof view.HTMLElement && node.dataset.reference) {
|
|
394
|
+
const index = indexes.get(node.dataset.reference);
|
|
395
|
+
node.dataset.highlightIndex = (typeof index === 'number') ? (index % 5 + 1).toString() : '?';
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
// this is a check for flushing text when we re-attach.
|
|
399
|
+
// @see AttachNode
|
|
400
|
+
entry.check = entry.node.innerHTML.length;
|
|
401
|
+
}
|
|
402
|
+
// dependencies is just the single list
|
|
403
|
+
const list = Array.from(map.values());
|
|
404
|
+
if (!force_event) {
|
|
405
|
+
if (JSON.stringify(this.composite_dependencies) === JSON.stringify(list)) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
this.composite_dependencies = list;
|
|
410
|
+
if (!toll_update) {
|
|
411
|
+
this.Publish({ type: 'update', dependencies: this.composite_dependencies });
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* get a list of all references in the text (actually in the parse result,
|
|
416
|
+
* since we have that). stores the list in the node descriptor (and in
|
|
417
|
+
* the node dataset).
|
|
418
|
+
*
|
|
419
|
+
* returns a list of the references in parse result mapped to normalized
|
|
420
|
+
* address labels. those can be used to identify identical references when
|
|
421
|
+
* we highlight later.
|
|
422
|
+
*
|
|
423
|
+
* @param parse_result
|
|
424
|
+
* @returns
|
|
425
|
+
*/
|
|
426
|
+
UpdateDependencies(descriptor, parse_result) {
|
|
427
|
+
const reference_list = [];
|
|
428
|
+
for (const unit of parse_result.full_reference_list || []) {
|
|
429
|
+
switch (unit.type) {
|
|
430
|
+
case 'address':
|
|
431
|
+
case 'range':
|
|
432
|
+
{
|
|
433
|
+
const start = unit.type === 'range' ? unit.start : unit;
|
|
434
|
+
if (!start.sheet_id) {
|
|
435
|
+
if (start.sheet) {
|
|
436
|
+
start.sheet_id = this.model.sheets.Find(start.sheet)?.id || 0;
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
start.sheet_id = this.view.active_sheet.id;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
reference_list.push(unit);
|
|
443
|
+
break;
|
|
444
|
+
}
|
|
445
|
+
case 'structured-reference':
|
|
446
|
+
if (this.target_address) {
|
|
447
|
+
const reference = this.model.ResolveStructuredReference(unit, this.target_address);
|
|
448
|
+
if (reference) {
|
|
449
|
+
reference_list.push(reference);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
console.info('target address not set');
|
|
454
|
+
}
|
|
455
|
+
break;
|
|
456
|
+
case 'identifier':
|
|
457
|
+
{
|
|
458
|
+
const named_range = this.model.GetName(unit.name, this.view.active_sheet.id); // FIXME: scoped?
|
|
459
|
+
if (named_range?.type === 'range') {
|
|
460
|
+
if (named_range.area.count === 1) {
|
|
461
|
+
reference_list.push({
|
|
462
|
+
type: 'address',
|
|
463
|
+
...named_range.area.start,
|
|
464
|
+
label: unit.name,
|
|
465
|
+
position: unit.position,
|
|
466
|
+
id: unit.id,
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
reference_list.push({
|
|
471
|
+
type: 'range',
|
|
472
|
+
start: {
|
|
473
|
+
type: 'address',
|
|
474
|
+
position: unit.position,
|
|
475
|
+
id: unit.id,
|
|
476
|
+
label: unit.name,
|
|
477
|
+
...named_range.area.start,
|
|
478
|
+
},
|
|
479
|
+
end: {
|
|
480
|
+
type: 'address',
|
|
481
|
+
position: unit.position,
|
|
482
|
+
label: unit.name,
|
|
483
|
+
id: unit.id,
|
|
484
|
+
...named_range.area.end,
|
|
485
|
+
},
|
|
486
|
+
label: unit.name,
|
|
487
|
+
position: unit.position,
|
|
488
|
+
id: unit.id,
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
break;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
// how could this ever be out of order? (...)
|
|
497
|
+
reference_list.sort((a, b) => a.position - b.position);
|
|
498
|
+
// flat list, unique
|
|
499
|
+
const references = [];
|
|
500
|
+
// set for matching
|
|
501
|
+
const list = new Set();
|
|
502
|
+
// for the result, map of reference to normalized address label
|
|
503
|
+
// const map: Map<ExpressionUnit, string> = new Map();
|
|
504
|
+
const map = new Map();
|
|
505
|
+
for (const entry of reference_list) {
|
|
506
|
+
const label = this.model.AddressToLabel(entry, true); // , this.view.active_sheet);
|
|
507
|
+
const area = IsCellAddress(entry) ?
|
|
508
|
+
new Area(entry) :
|
|
509
|
+
new Area(entry.start, entry.end);
|
|
510
|
+
// add to references once
|
|
511
|
+
if (!list.has(label)) {
|
|
512
|
+
references.push(area);
|
|
513
|
+
list.add(label);
|
|
514
|
+
}
|
|
515
|
+
// but keep a map
|
|
516
|
+
map.set(entry.label, label);
|
|
517
|
+
}
|
|
518
|
+
this.UpdateReferences(descriptor, references);
|
|
519
|
+
// console.info({map});
|
|
520
|
+
return map;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* store the set of references, and store in the node dataset for
|
|
524
|
+
* external clients.
|
|
525
|
+
*
|
|
526
|
+
* @param descriptor
|
|
527
|
+
* @param references
|
|
528
|
+
* @param options
|
|
529
|
+
*/
|
|
530
|
+
UpdateReferences(descriptor, references = []) {
|
|
531
|
+
descriptor.node.dataset.references = JSON.stringify(references.map(entry => this.model.AddressToLabel(entry, true)));
|
|
532
|
+
descriptor.references = references;
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* reformat text to highlight, which involves tinkering with
|
|
536
|
+
* node structure. we're probably doing this more than necessary;
|
|
537
|
+
* we might consider editing the existing structure, rather than
|
|
538
|
+
* throwing it away every time.
|
|
539
|
+
*
|
|
540
|
+
*/
|
|
541
|
+
UpdateText(
|
|
542
|
+
// node: HTMLElement,
|
|
543
|
+
descriptor, options = {}) {
|
|
544
|
+
const node = descriptor.node;
|
|
545
|
+
const text = node.textContent || '';
|
|
546
|
+
const DOM = DOMContext.GetInstance(node.ownerDocument);
|
|
547
|
+
// set this flag so we can use it in `get selected()`
|
|
548
|
+
this.text_formula = text[0] === '=';
|
|
549
|
+
if (this.active_editor && !this.assume_formula) {
|
|
550
|
+
this.active_editor.node.spellcheck = !(this.text_formula);
|
|
551
|
+
// if not assuming formula, and it's not a formula, then exit.
|
|
552
|
+
if (!this.text_formula) {
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
// this is a short-circuit so we don't format the same text twice.
|
|
557
|
+
// but there are some problems when you assign the same text over,
|
|
558
|
+
// especially if the text is empty.
|
|
559
|
+
//
|
|
560
|
+
// to unset this field make sure to set it to `undefined` instead
|
|
561
|
+
// of any empty string, so it will expressly not match an empty string.
|
|
562
|
+
if (text === descriptor.formatted_text) {
|
|
563
|
+
// fix selection behavior for tabbing
|
|
564
|
+
// for some reason this is too aggressive, it's happening when
|
|
565
|
+
// we _should_ have a selection
|
|
566
|
+
/*
|
|
567
|
+
if (node === this.editor_node && node === document.activeElement) {
|
|
568
|
+
const substr = this.SubstringToCaret(node);
|
|
569
|
+
const substr2 = this.SubstringToCaret(node, true);
|
|
570
|
+
if (text.length && substr === '' && substr2 === '') {
|
|
571
|
+
this.SelectAll(node);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
*/
|
|
575
|
+
// is there a case where we'd want to autocomplete here? (...)
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
// I wonder if this should be done asynchronously... we generally
|
|
579
|
+
// have pretty short strings, so maybe not a big deal
|
|
580
|
+
const [substring_start, substring_end] = this.SubstringToCaret2(node);
|
|
581
|
+
// console.info({text, substr, substr2});
|
|
582
|
+
const caret_start = substring_start.length;
|
|
583
|
+
let caret_end = substring_end.length;
|
|
584
|
+
// this is a little hacky
|
|
585
|
+
if (caret_start === 0 && caret_end === 0) {
|
|
586
|
+
caret_end = text.length;
|
|
587
|
+
}
|
|
588
|
+
if (!text) {
|
|
589
|
+
this.UpdateReferences(descriptor); // flush
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
const parse_result = this.parser.Parse(text);
|
|
593
|
+
if (parse_result.expression) {
|
|
594
|
+
const normalized_labels = this.UpdateDependencies(descriptor, parse_result);
|
|
595
|
+
// the parser will drop a leading = character, so be
|
|
596
|
+
// sure to add that back if necessary
|
|
597
|
+
const offset = (text[0] === '=' ? 1 : 0);
|
|
598
|
+
let start = 0;
|
|
599
|
+
let selection_start;
|
|
600
|
+
let selection_end;
|
|
601
|
+
// let selection_node: ChildNode|null = null;
|
|
602
|
+
// let selection_offset = 0;
|
|
603
|
+
let text_index = 0;
|
|
604
|
+
let last_text_node;
|
|
605
|
+
const fragment = DOM.Fragment();
|
|
606
|
+
const AddNode = (text, type = 'text', reference = '', force_selection = false) => {
|
|
607
|
+
const text_node = DOM.Text(text);
|
|
608
|
+
if (force_selection || ((caret_start > text_index || (caret_start === 0 && text_index === 0)) && caret_start <= text_index + text.length)) {
|
|
609
|
+
selection_start = {
|
|
610
|
+
offset: caret_start - text_index,
|
|
611
|
+
node: text_node,
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
if (caret_end > text_index && caret_end <= text_index + text.length) {
|
|
615
|
+
selection_end = {
|
|
616
|
+
offset: caret_end - text_index,
|
|
617
|
+
node: text_node,
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
if (type !== 'text') {
|
|
621
|
+
const span = DOM.Create('span', type);
|
|
622
|
+
if (reference) {
|
|
623
|
+
span.dataset.reference = reference;
|
|
624
|
+
}
|
|
625
|
+
// span.className = type;
|
|
626
|
+
span.appendChild(text_node);
|
|
627
|
+
fragment.appendChild(span);
|
|
628
|
+
}
|
|
629
|
+
else {
|
|
630
|
+
fragment.appendChild(text_node);
|
|
631
|
+
}
|
|
632
|
+
last_text_node = text_node;
|
|
633
|
+
text_index += text.length;
|
|
634
|
+
};
|
|
635
|
+
this.parser.Walk(parse_result.expression, (unit) => {
|
|
636
|
+
if (unit.type === 'missing' || unit.type === 'group' || unit.type === 'dimensioned') {
|
|
637
|
+
return true;
|
|
638
|
+
}
|
|
639
|
+
const pos = unit.position + offset;
|
|
640
|
+
const part = text.substring(start, pos);
|
|
641
|
+
let label = '';
|
|
642
|
+
let type = unit.type;
|
|
643
|
+
let reference = '';
|
|
644
|
+
switch (unit.type) {
|
|
645
|
+
case 'identifier':
|
|
646
|
+
// FIXME: canonicalize (optionally)
|
|
647
|
+
label = text.substring(pos, pos + unit.name.length);
|
|
648
|
+
reference = normalized_labels.get(unit.name) || '';
|
|
649
|
+
break;
|
|
650
|
+
case 'call':
|
|
651
|
+
// FIXME: canonicalize (optionally)
|
|
652
|
+
label = text.substring(pos, pos + unit.name.length);
|
|
653
|
+
break;
|
|
654
|
+
case 'literal':
|
|
655
|
+
if (typeof unit.value === 'string') {
|
|
656
|
+
label = text.substring(pos, pos + unit.value.length + 2);
|
|
657
|
+
type = 'string';
|
|
658
|
+
}
|
|
659
|
+
else {
|
|
660
|
+
return false;
|
|
661
|
+
}
|
|
662
|
+
break;
|
|
663
|
+
case 'address':
|
|
664
|
+
case 'range':
|
|
665
|
+
case 'structured-reference':
|
|
666
|
+
reference = normalized_labels.get(unit.label) || '???';
|
|
667
|
+
/*
|
|
668
|
+
{
|
|
669
|
+
const index = indexes.get(unit);
|
|
670
|
+
if (typeof index === 'number') {
|
|
671
|
+
type += ` highlight-${(index % 5) + 1}`
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
*/
|
|
675
|
+
// TODO: validate (optionally)
|
|
676
|
+
label = options.rewrite_addresses ? unit.label :
|
|
677
|
+
text.substring(pos, pos + unit.label.length);
|
|
678
|
+
break;
|
|
679
|
+
default:
|
|
680
|
+
// console.info('unhandled', unit.type);
|
|
681
|
+
return true;
|
|
682
|
+
}
|
|
683
|
+
AddNode(part);
|
|
684
|
+
AddNode(label, type, reference);
|
|
685
|
+
start = pos + label.length;
|
|
686
|
+
return unit.type !== 'range';
|
|
687
|
+
});
|
|
688
|
+
if (start < text.length) {
|
|
689
|
+
AddNode(text.substring(start));
|
|
690
|
+
}
|
|
691
|
+
if (!selection_start) {
|
|
692
|
+
// console.info('no selection node');
|
|
693
|
+
if (last_text_node) {
|
|
694
|
+
selection_start = {
|
|
695
|
+
node: last_text_node,
|
|
696
|
+
offset: (last_text_node.data || '').length,
|
|
697
|
+
};
|
|
698
|
+
// console.info('using last node');
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
// console.info('adding next selection node');
|
|
702
|
+
AddNode('', undefined, '', true);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
node.textContent = '';
|
|
706
|
+
node.appendChild(fragment);
|
|
707
|
+
if (selection_start && !options.format_only && node === this.active_editor?.node) {
|
|
708
|
+
this.SetCaret(selection_start, selection_end);
|
|
709
|
+
// we were doing this for the external editor, and it was useful
|
|
710
|
+
// because those editors don't grow. but it makes the spreadsheet
|
|
711
|
+
// scroll when it's used in the ICE/overlay. maybe a flag?
|
|
712
|
+
// (selection_end || selection_start).node.parentElement?.scrollIntoView();
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
else {
|
|
716
|
+
// console.warn("expression failed", text);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
descriptor.formatted_text = text;
|
|
720
|
+
//
|
|
721
|
+
const matcher = this.autocomplete_matcher;
|
|
722
|
+
if (matcher) {
|
|
723
|
+
Promise.resolve().then(() => {
|
|
724
|
+
const exec_result = matcher.Exec({ text, cursor: substring_end.length });
|
|
725
|
+
// fix behavior around "f16round", which is a function we accidentally
|
|
726
|
+
// inherit from Math in Safari and Firefox. it breaks arrow-selection
|
|
727
|
+
// because it pops up an AC window. we don't want to break AC behavior
|
|
728
|
+
// on tooltips, though, so we still want to call AC methods. just block
|
|
729
|
+
// the completion list.
|
|
730
|
+
if (this.selecting && exec_result.completions?.length) {
|
|
731
|
+
// console.info("Blocking completion list", JSON.stringify(exec_result.completions));
|
|
732
|
+
exec_result.completions = undefined;
|
|
733
|
+
}
|
|
734
|
+
const node = this.NodeAtIndex(exec_result.completions?.length ?
|
|
735
|
+
(exec_result.position || 0) :
|
|
736
|
+
(exec_result.function_position || 0));
|
|
737
|
+
this.Autocomplete(exec_result, node);
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
NodeAtIndex(index) {
|
|
742
|
+
const children = this.active_editor?.node.childNodes || [];
|
|
743
|
+
for (let i = 0; i < children.length; i++) {
|
|
744
|
+
const len = children[i].textContent?.length || 0;
|
|
745
|
+
if (len > index) {
|
|
746
|
+
return children[i];
|
|
747
|
+
}
|
|
748
|
+
index -= len;
|
|
749
|
+
}
|
|
750
|
+
return undefined;
|
|
751
|
+
}
|
|
752
|
+
AcceptAutocomplete(ac_result) {
|
|
753
|
+
if (!this.active_editor)
|
|
754
|
+
return;
|
|
755
|
+
// let type = DescriptorType.Function;
|
|
756
|
+
let type;
|
|
757
|
+
if (ac_result.data && ac_result.data.completions) {
|
|
758
|
+
for (const completion of ac_result.data.completions) {
|
|
759
|
+
if (completion.name.toLowerCase() === ac_result.value?.toLowerCase()) {
|
|
760
|
+
type = completion.type; // || DescriptorType.Function;
|
|
761
|
+
break;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
// since this only happens when typing, we know that there's a single
|
|
766
|
+
// cursor position, and it's in a text node. can we use that reduction to
|
|
767
|
+
// simplify how we insert? it's probably unecessary to highlight...
|
|
768
|
+
//
|
|
769
|
+
// at least in the case of functions. if we're inserting a named reference,
|
|
770
|
+
// then we do need to highlight. so.
|
|
771
|
+
const start = ac_result.data?.position || 0;
|
|
772
|
+
const end = start + (ac_result.data?.token?.length || 0);
|
|
773
|
+
const insertion = (type === 'token') ? ac_result.value : ac_result.value + '(';
|
|
774
|
+
const text = this.active_editor.node.textContent || '';
|
|
775
|
+
let adjusted = text.substring(0, start) + insertion;
|
|
776
|
+
const caret = adjusted.length;
|
|
777
|
+
adjusted += text.substring(end);
|
|
778
|
+
this.active_editor.node.textContent = adjusted;
|
|
779
|
+
this.SetCaret({ node: this.active_editor.node, offset: caret });
|
|
780
|
+
this.autocomplete?.Hide();
|
|
781
|
+
this.UpdateText(this.active_editor);
|
|
782
|
+
this.UpdateColors();
|
|
783
|
+
}
|
|
784
|
+
/** called when there's AC data to display (or tooltip) */
|
|
785
|
+
Autocomplete(data, target_node) {
|
|
786
|
+
if (!this.container_node || !this.autocomplete) {
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
let client_rect;
|
|
790
|
+
if (target_node?.nodeType === Node.ELEMENT_NODE) {
|
|
791
|
+
client_rect = target_node.getBoundingClientRect();
|
|
792
|
+
}
|
|
793
|
+
else {
|
|
794
|
+
client_rect = this.container_node.getBoundingClientRect();
|
|
795
|
+
}
|
|
796
|
+
// console.info({target_node, client_rect});
|
|
797
|
+
const rect = new Rectangle(Math.round(client_rect.left), Math.round(client_rect.top), client_rect.width, client_rect.height);
|
|
798
|
+
this.autocomplete.Show(this.AcceptAutocomplete.bind(this), data, rect);
|
|
799
|
+
}
|
|
800
|
+
/**
|
|
801
|
+
* this version gets substrings to both selection points.
|
|
802
|
+
*
|
|
803
|
+
* @param node
|
|
804
|
+
* @returns [substring to start of selection, substring to end of selection]
|
|
805
|
+
*/
|
|
806
|
+
SubstringToCaret2(node, force = false) {
|
|
807
|
+
const result = ['', ''];
|
|
808
|
+
if (!force && node !== node.ownerDocument.activeElement || node !== this.active_editor?.node) {
|
|
809
|
+
return result;
|
|
810
|
+
}
|
|
811
|
+
const doc = node.ownerDocument;
|
|
812
|
+
const view = doc.defaultView;
|
|
813
|
+
// is there a way to do this without recursing? (...)
|
|
814
|
+
// how about string concat instead of array join, it's faster in
|
|
815
|
+
// chrome (!)
|
|
816
|
+
const complete = [false, false];
|
|
817
|
+
const Consume = (element, range) => {
|
|
818
|
+
// it only seems to happen in firefox, but sometimes we'll get
|
|
819
|
+
// a non-text node that is the start container and endcontainer.
|
|
820
|
+
//
|
|
821
|
+
// in that case we need to interpret the endOffset as nodes, not
|
|
822
|
+
// characters. that's what's causing the firefox issues. I guess
|
|
823
|
+
// that applies to startoffset as well?
|
|
824
|
+
// not sure if this is bugged or what but when we hit this case,
|
|
825
|
+
// it's always "all the text in there" regardless of the offsets.
|
|
826
|
+
// not sure what the offsets are even referring to, since we get
|
|
827
|
+
// offsets > the number of child nodes. is this a bug in firefox?
|
|
828
|
+
if (element === range.startContainer && element === range.endContainer && !(element instanceof view.Text)) {
|
|
829
|
+
/*
|
|
830
|
+
if (range.startOffset !== 0 || range.endOffset !== 0) {
|
|
831
|
+
console.info("warn offset", range.startOffset, range.endOffset);
|
|
832
|
+
console.info(element);
|
|
833
|
+
}
|
|
834
|
+
*/
|
|
835
|
+
complete[0] = complete[1] = true;
|
|
836
|
+
result[0] += element.textContent;
|
|
837
|
+
result[1] += element.textContent;
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
if (element === range.startContainer) {
|
|
841
|
+
result[0] += (element.textContent || '').substring(0, range.startOffset);
|
|
842
|
+
complete[0] = true;
|
|
843
|
+
}
|
|
844
|
+
if (element === range.endContainer) {
|
|
845
|
+
result[1] += (element.textContent || '').substring(0, range.endOffset);
|
|
846
|
+
complete[1] = true;
|
|
847
|
+
}
|
|
848
|
+
if (complete[0] && complete[1]) {
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
if (element instanceof view.Text) {
|
|
852
|
+
const text = element.textContent || '';
|
|
853
|
+
if (!complete[0]) {
|
|
854
|
+
result[0] += text;
|
|
855
|
+
}
|
|
856
|
+
if (!complete[1]) {
|
|
857
|
+
result[1] += text;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
else if (element.hasChildNodes()) {
|
|
861
|
+
for (const child of Array.from(element.childNodes)) {
|
|
862
|
+
Consume(child, range);
|
|
863
|
+
if (complete[0] && complete[1]) {
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
const selection = view.getSelection();
|
|
870
|
+
if (selection?.rangeCount ?? 0 > 0) {
|
|
871
|
+
const range = selection?.getRangeAt(0);
|
|
872
|
+
if (range) {
|
|
873
|
+
Consume(node, range);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
return result;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
//# sourceMappingURL=editor.js.map
|