-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: calculte supports tenary and conditionals
- update to functional programing
- Loading branch information
1 parent
9e2ea92
commit a74713e
Showing
1 changed file
with
112 additions
and
120 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,177 +1,169 @@ | ||
import observer from '@cocreate/observer'; | ||
import { getAttributes } from '@cocreate/utils'; | ||
// import { renderValue } from '@cocreate/render'; | ||
import '@cocreate/element-prototype'; | ||
|
||
var CoCreateCalculation = { | ||
|
||
init: function () { | ||
let calculationElements = document.querySelectorAll('[calculate]'); | ||
this.initElements(calculationElements); | ||
}, | ||
function init() { | ||
let calculationElements = document.querySelectorAll('[calculate]'); | ||
initElements(calculationElements); | ||
} | ||
|
||
initElements: function (elements) { | ||
for (let el of elements) | ||
this.initElement(el); | ||
}, | ||
function initElements(elements) { | ||
for (let el of elements) | ||
initElement(el); | ||
} | ||
|
||
initElement: function (ele) { | ||
const self = this; | ||
let calculation = ele.getAttribute('calculate'); | ||
let selectors = this.getSelectors(calculation); | ||
function initElement(element) { | ||
let calculation = element.getAttribute('calculate'); | ||
if (calculation.includes('{{') || calculation.includes('{[')) | ||
return; | ||
|
||
for (let i = 0; i < selectors.length; i++) { | ||
let id = selectors[i]; | ||
if (id.includes('{{')) return; | ||
let selectors = getSelectors(calculation); | ||
|
||
// self.initEvents(ele, id); | ||
let inputs = document.querySelectorAll(id); | ||
for (let input of inputs) { | ||
self.initEvent(ele, input); | ||
} | ||
for (let i = 0; i < selectors.length; i++) { | ||
// if (selectors[i].includes('{{')) return; | ||
|
||
observer.init({ | ||
name: 'calculationSelectorInit', | ||
observe: ['addedNodes'], | ||
target: id, | ||
callback: function (mutation) { | ||
self.initEvent(ele, mutation.target); | ||
self.setCalcationResult(ele); | ||
} | ||
}); | ||
|
||
self.setCalcationResult(ele); | ||
// initEvents(element, selectors[i]); | ||
let inputs = document.querySelectorAll(selectors[i]); | ||
for (let input of inputs) { | ||
initEvent(element, input); | ||
} | ||
}, | ||
|
||
initEvent: function (ele, input) { | ||
const self = this; | ||
input.addEventListener('input', function () { | ||
self.setCalcationResult(ele); | ||
observer.init({ | ||
name: 'calculationSelectorInit', | ||
observe: ['addedNodes'], | ||
target: selectors[i], | ||
callback(mutation) { | ||
initEvent(element, mutation.target); | ||
setCalcationResult(element); | ||
} | ||
}); | ||
} | ||
setCalcationResult(element); | ||
} | ||
|
||
// if (input.hasAttribute('calculate')) { | ||
// input.addEventListener('changedCalcValue', function(e) { | ||
// self.setCalcationResult(ele); | ||
// }); | ||
// } | ||
// self.setCalcationResult(ele); | ||
}, | ||
|
||
getSelectors: function (string) { | ||
let tmp = string; | ||
|
||
let selectors = []; | ||
if (!tmp) return selectors; | ||
while (tmp.length > 0) { | ||
let firstIndex = tmp.indexOf('{'); | ||
let secondIndex = tmp.indexOf('}', firstIndex); | ||
|
||
if (firstIndex > -1 && secondIndex > -1) { | ||
let id = tmp.substring(firstIndex + 1, secondIndex); | ||
|
||
if (selectors.indexOf(id) == -1) selectors.push(id); | ||
function getSelectors(string) { | ||
let regex = /\{\((?:(?!\{\().)*?\)\}/; | ||
let selectors = []; | ||
|
||
tmp = tmp.substring(secondIndex + 1); | ||
let match; | ||
while ((match = regex.exec(string)) !== null) { | ||
// Extract the content inside the braces (excluding the leading '{(' and trailing ')}') | ||
let selector = match[0].slice(2, -2); | ||
|
||
} | ||
else { | ||
return selectors; | ||
} | ||
if (selectors.indexOf(selector) === -1) { | ||
selectors.push(selector); | ||
} | ||
|
||
return selectors; | ||
}, | ||
// Replace the found match with an empty string to avoid reprocessing in the next iteration | ||
string = string.replace(match[0], ''); | ||
} | ||
|
||
return selectors; | ||
} | ||
|
||
getValues: async function (calculation) { | ||
let selectors = this.getSelectors(calculation); | ||
async function getValues(calculation) { | ||
let selectors = getSelectors(calculation); | ||
|
||
for (let i = 0; i < selectors.length; i++) { | ||
let selector = selectors[i]; | ||
for (let i = 0; i < selectors.length; i++) { | ||
let selector = selectors[i]; | ||
|
||
let value = null; | ||
let inputs = document.querySelectorAll(selector); | ||
let value = null; | ||
let inputs = document.querySelectorAll(selector); | ||
|
||
for (let input of inputs) { | ||
let val = null; | ||
if (input.getValue) | ||
val = Number(await input.getValue()); | ||
for (let input of inputs) { | ||
let val = null; | ||
if (input.getValue) | ||
val = Number(await input.getValue()); | ||
|
||
if (!Number.isNaN(value)) { | ||
value += val; | ||
} | ||
if (!Number.isNaN(value)) { | ||
value += val; | ||
} | ||
} | ||
|
||
if (value != null && !Number.isNaN(value)) { | ||
calculation = calculation.replaceAll('{' + selector + '}', value); | ||
} | ||
if (value != null && !Number.isNaN(value)) { | ||
calculation = calculation.replaceAll('{' + selector + '}', value); | ||
} | ||
} | ||
|
||
return calculation; | ||
}, | ||
return calculation; | ||
} | ||
|
||
setCalcationResult: async function (element) { | ||
const { object, isRealtime } = getAttributes(element); | ||
let calculation = element.getAttribute('calculate'); | ||
function initEvent(element, input) { | ||
input.addEventListener('input', function () { | ||
setCalcationResult(element); | ||
}); | ||
|
||
// if (input.hasAttribute('calculate')) { | ||
// input.addEventListener('changedCalcValue', function(e) { | ||
// setCalcationResult(element); | ||
// }); | ||
// } | ||
// setCalcationResult(element); | ||
} | ||
|
||
let calString = await this.getValues(calculation); | ||
async function setCalcationResult(element) { | ||
const { object, isRealtime } = getAttributes(element); | ||
let calculation = element.getAttribute('calculate'); | ||
|
||
if (calString) { | ||
let result = calculate(calString); | ||
let calString = await getValues(calculation); | ||
|
||
// TODO: input event below triggers save for all input elements but will not save for regular elements | ||
if (element.setValue) { | ||
element.setValue(result) | ||
if (object && isRealtime != "false") { | ||
element.save(element); | ||
} | ||
} | ||
else { | ||
// if (element.value){ | ||
if (calString) { | ||
let result = calculate(calString); | ||
|
||
// } | ||
// else { | ||
element.innerHTML = result; | ||
// } | ||
// TODO: input event below triggers save for all input elements but will not save for regular elements | ||
if (element.setValue) { | ||
element.setValue(result) | ||
if (object && isRealtime != "false") { | ||
element.save(element); | ||
} | ||
} | ||
else { | ||
// if (element.value){ | ||
|
||
let inputEvent = new CustomEvent('input', { bubbles: true }); | ||
Object.defineProperty(inputEvent, 'target', { writable: false, value: element }); | ||
element.dispatchEvent(inputEvent); | ||
|
||
//. set custom event | ||
// var event = new CustomEvent('changedCalcValue', { | ||
// bubbles: true, | ||
// }); | ||
// element.dispatchEvent(event); | ||
// } | ||
// else { | ||
element.innerHTML = result; | ||
// } | ||
} | ||
|
||
}, | ||
let inputEvent = new CustomEvent('input', { bubbles: true }); | ||
Object.defineProperty(inputEvent, 'target', { writable: false, value: element }); | ||
element.dispatchEvent(inputEvent); | ||
|
||
}; | ||
//. set custom event | ||
// var event = new CustomEvent('changedCalcValue', { | ||
// bubbles: true, | ||
// }); | ||
// element.dispatchEvent(event); | ||
} | ||
|
||
} | ||
|
||
function calculate(string) { | ||
if (!string.match(/[a-z_]/i)) | ||
if (/^[0-9+\-*/()%||?\s:=.]*$/.test(string)) | ||
return eval(string); | ||
} | ||
|
||
observer.init({ | ||
name: 'CoCreateCalculationChangeValue', | ||
observe: ['attributes'], | ||
attributeName: ['calculate'], | ||
callback: function (mutation) { | ||
CoCreateCalculation.setCalcationResult(mutation.target); | ||
callback(mutation) { | ||
setCalcationResult(mutation.target); | ||
} | ||
}); | ||
|
||
observer.init({ | ||
name: 'CoCreateCalculationInit', | ||
observe: ['addedNodes'], | ||
target: '[calculate]', | ||
callback: function (mutation) { | ||
CoCreateCalculation.initElement(mutation.target); | ||
callback(mutation) { | ||
initElement(mutation.target); | ||
} | ||
}); | ||
|
||
CoCreateCalculation.init(); | ||
init(); | ||
|
||
export default CoCreateCalculation; | ||
export default { initElements, initElement, calculate }; |