1
0
Fork 0
mirror of synced 2024-06-27 02:20:35 +12:00

Updating data bindings, there were instances where it could loop/iterate over already replaced bindings, used a search technique to be a bit more specific about the replacements and make sure each binding could only be replaced once.

This commit is contained in:
mike12345567 2021-09-30 17:24:43 +01:00
parent ec63adf567
commit c7bc68d0de

View file

@ -1,12 +1,12 @@
import { cloneDeep } from "lodash/fp" import { cloneDeep } from "lodash/fp"
import { get } from "svelte/store" import { get } from "svelte/store"
import { import {
findAllMatchingComponents,
findComponent, findComponent,
findComponentPath, findComponentPath,
findAllMatchingComponents,
} from "./storeUtils" } from "./storeUtils"
import { store } from "builderStore" import { store } from "builderStore"
import { tables as tablesStore, queries as queriesStores } from "stores/backend" import { queries as queriesStores, tables as tablesStore } from "stores/backend"
import { makePropSafe } from "@budibase/string-templates" import { makePropSafe } from "@budibase/string-templates"
import { TableNames } from "../constants" import { TableNames } from "../constants"
@ -422,6 +422,10 @@ function shouldReplaceBinding(currentValue, from, convertTo) {
return !invalids.find(invalid => noSpaces?.includes(invalid)) return !invalids.find(invalid => noSpaces?.includes(invalid))
} }
function replaceBetween(string, start, end, replacement) {
return string.substring(0, start) + replacement + string.substring(end)
}
/** /**
* utility function for the readableToRuntimeBinding and runtimeToReadableBinding. * utility function for the readableToRuntimeBinding and runtimeToReadableBinding.
*/ */
@ -431,6 +435,7 @@ function bindingReplacement(bindableProperties, textWithBindings, convertTo) {
if (typeof textWithBindings !== "string") { if (typeof textWithBindings !== "string") {
return textWithBindings return textWithBindings
} }
// work from longest to shortest
const convertFromProps = bindableProperties const convertFromProps = bindableProperties
.map(el => el[convertFrom]) .map(el => el[convertFrom])
.sort((a, b) => { .sort((a, b) => {
@ -440,12 +445,29 @@ function bindingReplacement(bindableProperties, textWithBindings, convertTo) {
let result = textWithBindings let result = textWithBindings
for (let boundValue of boundValues) { for (let boundValue of boundValues) {
let newBoundValue = boundValue let newBoundValue = boundValue
// we use a search string, where any time we replace something we blank it out
// in the search, working from longest to shortest so always use best match first
let searchString = newBoundValue
for (let from of convertFromProps) { for (let from of convertFromProps) {
if (shouldReplaceBinding(newBoundValue, from, convertTo)) { if (shouldReplaceBinding(newBoundValue, from, convertTo)) {
const binding = bindableProperties.find(el => el[convertFrom] === from) const binding = bindableProperties.find(el => el[convertFrom] === from)
while (newBoundValue.includes(from)) { let idx
newBoundValue = newBoundValue.replace(from, binding[convertTo]) do {
} // see if any instances of this binding exist in the search string
idx = searchString.indexOf(from)
if (idx !== -1) {
let end = idx + from.length,
searchReplace = Array(binding[convertTo].length).join("*")
// blank out parts of the search string
searchString = replaceBetween(searchString, idx, end, searchReplace)
newBoundValue = replaceBetween(
newBoundValue,
idx,
end,
binding[convertTo]
)
}
} while (idx !== -1)
} }
} }
result = result.replace(boundValue, newBoundValue) result = result.replace(boundValue, newBoundValue)