
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
be-calculating
Advanced tools
Calculate the (text) value of the adorned element based on peer element (text) values.
be-calculating is basically the code-first counterpoint to the declarative be-observant enhancement, when the full power of the JavaScript run time engine is needed from the get-go.
Calculate value of the output element from peer input elements.
<form>
<input type=range id=a name=a value=50>
+<input type=number id=b name=b value=25>
=
<output name=result for="a b" be-calculating=+></output>
</form>
be-calculating is the canonical name for this enhancement. In less formal settings, where clashes between libraries can be avoided and concerns about HTML5 compliance aren't required, we can make use of alternative names. This package provides support for one:
<form>
<input type=range id=a name=a value=50>
+<input type=number id=b name=b value=25>
=
<output name=result for="a b" 🧮=+></output>
</form>
What this does: The output element displays the sum of a and b, updated the moment the user changes either one of them. I.e. it is listening to the input events for a and b (and no other elements).
Other "built in" calculators are shown below:
| Operator | Notes |
|---|---|
| + | Sums the args |
| * | Product of the args |
| max | Maximum of the args |
| min | Minimum of the args |
<form>
<input type=range id=a name=a value=50>
*<input type=number id=b name=b value=25>
=
<output name=result for="a b" 🧮=*></output>
</form>
<form>
max( <input type=range id=a name=a value=50>
,<input type=number id=b name=b value=25>)
=
<output name=result for="a b" 🧮=max></output>
</form>
Unfortunately, the platform has proven to be quite unfriendly to HTML-first solutions (due to "framework capture" politics, where browser vendors seem much more interested in shmoozing with framework authors than serving end user needs). I would have preferred supporting inline event handlers (which a previous incarnation supported), but this is not able to survive "minimal" security settings scrutiny. A makeshift userland solution could have solved this, but the main benefit of inline event handlers is to allow the browser to parse the handlers, which that solution doesn't solve. So the solutions below (global, local) seem to be the best solution given these headwinds.
The developer can create a custom calculating function, as shown below. Doing so will cascade through the page into any ShadowDOM realms. The advantages is it makes it highly reusable. The thing to be cautious about is that it is "global" within the confines of all the elements adorned by the 🧮 attribute.
<script type=module blocking=render>
(await (import'be-calculating/🧮.js'))
.register('linear', e => e.r = e.f.m * e.f.x + e.f.b)
;
</script>
<form>
<label>
m
<input type=number id=m value=2>
</label>
<label>
x
<input type=number id=x value=2>
</label>
+ <label>
b
<input type=number id=b value=25>
</label>
=
<output name=result for="m x b" 🧮=linear></output>
</form>
In the javascript expression at the top, "f" stands for "factors", "r" for "result" or "return".
So the event provides the "f" property, which is basically the factors we want the calculation based on -- the names (id's in this case) of the values.
But in some cases, we don't want to base our expression on the names or id's of the elements, but instead on the position (or maybe the arguments are all treated the same). So we can apply our expression to the the array of arguments corresponding to the elements. In fact, the examples in part I were using reducers based on the args property of the event. So built in to 🧮 are registered event handlers such as
Registry.register(emc, '+', e => e.r = e.args.reduce((acc, arg) => acc + arg));
A framework or custom element host or local script element can attach a local event listener to the output element and compute the value
<form>
<label>
m
<input type=number id=m value=2>
</label>
<label>
x
<input type=number id=x value=2>
</label>
+ <label>
b
<input type=number id=b value=25>
</label>
=
<output id=output name=result for="m x b" 🧮></output>
<script>
output.addEventListener('🧮', e => e.r = e.f.m * e.f.x + e.f.b);
</script>
</form>
The example above, while simple has a number of issues:
So to do the example above in a way that addresses these concerns, we can go in one of two ways, each with their advantages and disadvantages:
<form>
<label>
m
<input type=number id=m value=2>
</label>
<label>
x
<input type=number id=x value=2>
</label>
+ <label>
b
<input type=number id=b value=25>
</label>
=
<output name=result for="m x b" 🧮-js="f.m * f.x + f.b"></output>
</form>
By "CSP Safe," I mean that with minimal standard protections in place, the browser will provide a blocking error when it doesn't find a matching csp hash value, and provide what that hash value needs to be, so that with enough patience, or with a good build engine, http headers or a meta tag such as what we see below can put the browser at ease:
<meta http-equiv="Content-Security-Policy"
content="
default-src 'self'; style-src 'self'; img-src 'self';
script-src
'sha256-NdPEJFVQRHzDnDETRYKcvXUeTTDl5bEC5BpjzeA22yE='
'sha256-i6TvqP2TVtG9MVoQx7msqKMo9N5gKfwHr7cZVV6d4xg='
'sha256-kYCKyd++EI0QB9YUHtFWecp5JC9aEMAJXKYs627N97A='
'sha256-WKHAJV10n+uRXN4tBgzWP2+xzIHx17UDLYsfih7sDCI='
'sha256-NwD1Uj3szNXySAwCTzxmKecgUosm4JX/FH81ae1I92o='
'sha256-/0HNY8ZMkctGwbm9m0+ixgmu4QFFJXOLg92huDNwWks='
;
">
Each calculated expression should only result in one hash code, regardless of how many times the JS expression is repeated throughout the application.
Up to now, we've been defaulting the event type to "input" as far as knowing when to update the calculation. But we can tweak that as shown below:
<form>
<input type="range" id="a" value="50">
+<input type="number" id="b" value="25">
=<output for="a b" 🧮=+ 🧮-on=change ></output>
</form>
Anything that requires subscribing to alternative or mixed event names, and/or that requires referencing nearby elements using something other than id's, needs to use an alternative to the for attribute. We do so by adopting DSS to describe what to observe, and optionally when to act.
<form>
<input type="range" name=a value="50">
+<input type="number" name=b value="25">
=<output 🧮-for="@a and @b" 🧮=+></output>
</form>
This still happens to assume, by default, that the "input" event is what we should listen for, but having adopted DSS syntax, we can specify any other event name we may want. Id's and the for attribute are generated automatically by be-calculating in order to optimize our accessibility experience (if the for attribute/htmlFor property is found to be null/undefined).
This enhancement also supports other elements.
Let's go in the opposite direction from before -- local to more global
Once again, a framework or custom element host or local script can work in partnership with be-calculating/🧮:
<input name=domain value=emojipedia.org>
<input name=search value=calculator>
<a id=link 🧮-for="@domain and @search">
Emoji link
</a>
<script>
link.addEventListener('🧮', e => e.r = `https://${e.f.domain}/search?q=${e.f.search}`)
</script>
Or we can use an inline event handler that is still "csp-safe":
<input name=domain value=emojipedia.org>
<input name=search value=calculator>
<a id=link 🧮-for="@domain and @search" 🧮-js="`https://${f.domain}/search?q=${f.search}`">
Emoji link
</a>
(Using a form for the above example may be the better way to go).
In the examples above, we engaged in "mind reading" in order to pass to the event handler the precise values we want to use in order to calculate the result.
The DSS syntax this package relies on allows us to override these mind readings, and specify which property to pass.
But what if you encounter this situation:
Thanks but no thanks to all your "mind reading" -- could you please just pass in the dependent elements when they change? I have full, unfettered access to the JavaScript engine, so I can just extract things out of the elements that I need without your help!
To do so, specify this as follows:
<form>
<input type="range" id="a" value="50">
+<input type="number" id="b" value="25">
=<output id=output 🧮-for="#a?.$0 and #b?.$0"></output>
<script>
output.addEventListener('🧮', e => e.r = e.f.a.valueAsNumber + e.f.b.valueAsNumber);
</script>
</form>
In particular, DSS now supports ?.$0 to specify the element itself as the thing that needs passing.
Any web server that serves static files and server-side includes will do but...
npm install
npm run serve
import 'be-calculating/be-calculating.js';
<script type=module crossorigin=anonymous>
import 'https://esm.run/be-calculating';
</script>
FAQs
Set the value of an element based on peer elements or the host
We found that be-calculating demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.