Saturday, August 28, 2021

RedSys

I'm 

Tuesday, August 3, 2021

updateComps

Qedy.js separates the internal object model from the DOM. It's not a virtual DOM or a shadow DOM, because it doesn't care about HTML. In fact, the model itself is output format agnostic and only Converters know all the links between Components and DOM Elements. If Qedy decides a Comp should be updated, it simply asks the Converter to make it happen.

And because working with objects is fast and working with DOM is not, I implemented a system, where all the interactions are with the model only and at the end of a method call there's a call to updateComps, which passes all the changes to appropriate Converters to make them into DOM.

Because working with Converters is expensive, to prevent unnecessary calls, there's a reduction phase. For example, changing mode currently redraws the whole Comp, so if it has a child Comps, you can eliminate all their updates, because they'll be processed anyway while rebuilding the Comp.

Before this phase there's another quick loop, preloading Converters and applying scope-wide updates, like focusing a form field. This can't be done in during the reduction, because we don't control in which order the updates are, so it could be reduced before it was processed.

With the final list of updates ready, it's time to do the job. Mode changes are processed first for reasons mentioned above, and all other updated are processed afterwards. There are two basic categories: Singe (replace value) and multiple (add & remove value). All converters return a Promise, which is added into an array and ultimately Promise.all(promises) is called.

And the last part is focusing the required element. It finds the first visible instance (offsetParent is not null) and applies 10 ms delay to work properly even with mousedown event.

There's a limitation though, because I use lazy loading for Converters (so Qedy doesn't load them for hidden Components), it's not possible to use some Converter calls, like custom methods, which are Conv dependent – like changing label (heading).

There are several workarounds, like using .set("label", "abc"); method or assign the value directly with this.comps.myComp.label = "abc";.