if-diff

WebJar for if-diff

License

License

MIT
GroupId

GroupId

org.webjars.bowergithub.bahrus
ArtifactId

ArtifactId

if-diff
Last Version

Last Version

0.0.3
Release Date

Release Date

Type

Type

jar
Description

Description

if-diff
WebJar for if-diff
Project URL

Project URL

http://webjars.org
Source Code Management

Source Code Management

https://github.com/bahrus/if-diff

Download if-diff

How to add to project

<!-- https://jarcasting.com/artifacts/org.webjars.bowergithub.bahrus/if-diff/ -->
<dependency>
    <groupId>org.webjars.bowergithub.bahrus</groupId>
    <artifactId>if-diff</artifactId>
    <version>0.0.3</version>
</dependency>
// https://jarcasting.com/artifacts/org.webjars.bowergithub.bahrus/if-diff/
implementation 'org.webjars.bowergithub.bahrus:if-diff:0.0.3'
// https://jarcasting.com/artifacts/org.webjars.bowergithub.bahrus/if-diff/
implementation ("org.webjars.bowergithub.bahrus:if-diff:0.0.3")
'org.webjars.bowergithub.bahrus:if-diff:jar:0.0.3'
<dependency org="org.webjars.bowergithub.bahrus" name="if-diff" rev="0.0.3">
  <artifact name="if-diff" type="jar" />
</dependency>
@Grapes(
@Grab(group='org.webjars.bowergithub.bahrus', module='if-diff', version='0.0.3')
)
libraryDependencies += "org.webjars.bowergithub.bahrus" % "if-diff" % "0.0.3"
[org.webjars.bowergithub.bahrus/if-diff "0.0.3"]

Dependencies

compile (1)

Group / Artifact Type Version
org.webjars.bowergithub.polymer : polymer jar [2.0.0,3)

Project Modules

There are no modules declared in this project.

Published on webcomponents.org

Actions Status

<if-diff>

<if-diff> is an alternative to Polymer's dom-if element that allows comparison between two operands, as well as progressive enhancement. See if-else for another data-centric alternative.

if-diff allows the server to display content that should be initially displayed, then adjusts what is displayed as conditions in the browser change.

For example, suppose today is Monday. The server could generate the syntax below:

<!-- Framework-neutral pseudo code:  Assume some framework / library sets property "lhs" based on lhs:=dayOfWeek attribute --> 
<if-diff if lhs:=dayOfWeek equals rhs=Monday data-key-name=manicMonday m=1></if-diff>
...
<if-diff if lhs:=dayOfWeek equals rhs=Tuesday data-key-name=rubyTuesday></if-diff>
...
<div data-manic-monday="1">
  I wish it was Sunday
</div>
<div data-ruby-tuesday="0">
  <template>
    <div>Who could hang a name on you</div>
  </template>
</div>
...

Generally, as we will see, a data-* value of "1" should be interpreted as "matches", so assuming your css is consistent with that interpretation, the user will immediately see the desired text "I wish it was Sunday" before a single byte of JS is downloaded. Since the text for Tuesday is not yet applicable, embedding the content inside a template tag will allow the browser to ignore whatever is inside until needed. Only if the day changes would we need to display Tuesday. At that point, the template needs to be cloned (and discarded). So to fill in the details:

Rules:

  1. The "data-key-name" attribute refers to a data-* attribute / dataset.* property. The case is based on the property name.
  2. Only downstream sibling elements are checked for the data-* attribute. This is to encourage unidirectional data flow, and keeping related things physically close.
  3. Speaking of which, the optional m attribute indicates the maximum number of elements that are getting affected by the if-diff tag. Placing the if-diff element right above the element(s) it affects, and specifying "m" accurately, will improve performance and help reduce greenhouse emissions.
  4. if-diff sets the data-* attribute to "1" when the condition is true, "-1" if not. It is up to the application's css styling to interpret how this should display.
  5. If if-diff encounters a data-* value of "0", this signifies there's exactly one template inside the DOM element, which needs cloning before changing to "1". It will leave the template untouched if the condition is not satisfied. This allows for lazy loading, especially if combined with a dynamic loader, like xtal-sip.
  6. The "if" attribute / property is actually an active participant in the logical evaluation. If that attribute / property is false, then the evaluation will be false no matter what. And as the demo below indicates, not_equals is also supported, as is "includes." Additional / alternative evaluation logic can be inserted by overriding method async evaluate();

Demo

Syntax

Commonality with p-et-alia (a kind of dom-bind alternative)

Not only does if-diff share the same fetish for unidirectional data flow as p-et-alia, they share a number of common modules.

How to treat non visible content

What should we do with previously activated content that is now no longer applicable for the time being? I.e. what should happen on Wednesday?

if-diff's bias is towards hiding rather than deleting.

But if-diff agrees with dom-if's wisdom as far as the no-right-answer / difficult trade-offs, and envies how dom-if empowers developers to be able to choose if ending DOM support is the more humane thing to do.

Go to sleep mode

It is quite common to have a user interface with multiple tabs, each tab depending on some common filters / inputs. if-diff can be used in this scenario, and to help improve performance, it can toggle the disabled attribute on the target elements. If the elements themselves know how to "go to sleep" when disabled, and then sync up with the new filters / inputs when disabled is removed, that could provide the most optimal performance in a desktop / well-equipped tablet.

You can specify which elements to disable/enable based on the evaluation:

<if-diff if -lhs equals -rhs data-key-name=manicMonday m=1 enable="my-sleeping-element"></if-diff>

The enable attribute will cause if-diff to find all elements matching the enable value (via css querySelectorAll), and remove all disabled attributes from matching nodes, when the test is true, and add the disabled attribute when the test is false.

Prop Passing

More info on this in a later version.

Put to sleep mode

What if you need to deal with removing lots of DOM elements from view on a low memory device?

So now, in order to free up memory for new DOM elements that need to display, we need to ask out of scope DOM elements that have seen better days to throw themselves off a cliff.

A different element supports this harsh environment -- if-diff-then-stiff, a riff on a gif

The problem is, how can we restore / reincarnate the content from the dead, including its current state of properties / attributes, when time once again fails to freeze at Sunday midnight? There are no "serializeThis", "deserializeThat" functions available in the DOM API, like there is for JS Objects <=> JSON.

Aha! I can sense you glibly thinking via the Force.

"See, I told you -- you need a high-powered state manager, full of stores, thunking and discombobulating, to guide you through this resurrection of the UI."

But if the purpose of this whole exercise is to reduce memory, isn't that almost defeating the purpose? Granted, JavaScript objects often take up less memory than DOM elements, but now you have to hold on to both (more or less).

if-diff-then-stiff argues "Why would you store state of these snuffed out DOM elements in the extremely limited RAM, leaving less room for keeping additional DOM in memory? That seems incredibly cruel. Why not store the 'state' in out-of-RAM storage areas, such as history.state (at least past states), a remote store, IndexedDB, or SessionStorage?"

Viewing Your Element Locally

$ npm install
$ npm run serve
Open http://localhost:3030/demo/dev

Running Tests

$ npm test

Versions

Version
0.0.3