An introduction to ConditionerJS and the problems it tries to tackle, a presentation given at a Fronteers meetup hosted by Kabisa.
ConditionerFrizz Free, Environment-aware,JavaScript Modules
View Slide
Freelance Front-end DeveloperRik Schennink@rikschennink
originsAnother day another framework
Writing maintainable JavaScriptfor big web platforms is though.Now do it for the multi device web,k-thanks-bye!
no pixels lot’s of pixels
touchmouse pengestureremotevoicekeyboardvirtualgyrono pixels lot’s of pixels
It’s all a bit overwhelming.
Let’s take a step back.
Can’t make decisions based on device type.“Phone or tablet… fablet… god dammit.”
Features are way more interesting.“User moves his mouse… and the viewport is pretty wide…”
HTML works everywhere.
Features are stable while context is volatile.
Screensize“User resizes the window or rotates his device…”Input type“User interacts with touch then moves to his mouse…”Cookie support“User decides to not allow cookies…”
These changes give us valuable infoabout the context the user is in.
“We want to measure the users’ contextand respond appropriately.”
touchmouse pengestureremotevoicekeyboardvirtualgyroCURRENTTIMELIGHTLEVELSESSIONLENGTHNAVIGATIONHISTORYSCROLLPOSITIONproximityLOCATIONVELOCITYWEATHERCONNECTIONSTABILITYHISTORICALBEHAVIORMOTION
demo
HOW DO I USE ITProgramming principleshttps://www.flickr.com/photos/j_regan/6454408915/in/photostream/
game developmentA quick side track
Game development turned out to bemore difficult than expected.
How to make these systems play nice together…Particle engineAchievement dispenserGame loopRender engineCollision detection
How to make these systems play nice together…I had no clue…
My developer skills were lacking, Ineeded engineering skills.
The most important take-away…
Single Responsibility Principle
Using this principle while examining theresponsive web I found why my codespiralled out of control each time.
A typical piece of code was…Feature testingWaiting forDOMContentLoadedMonitoring eventsExpecting othercode
So in the next project, I separated allcode using modules based on AMD.
I needed to build an entity that couldload those modules without taking toomuch responsibility.
That entity is Conditioner.And it’s build on the following3 principles.
1. module isolationA strict separation between modules
Modules are separated for maintainability.
You bind modules in the HTML itself.
index.htmldata-module="ui/GoogleMap"> View on GoogleMaps
ui/GoogleMap.jsdefine(function(){ var exports = function GoogleMap(element) { }; return exports; });
document.querySelectorAll("[data-module]");
Conditioner measures context and will loadall relevant modules without knowinganything about them.Just that they’re bound with data-module.
2. module decouplingMaking modules environment agnostic
Setup context parameters using the“data-conditions” attribute.
index.htmldata-module="ui/GoogleMap" data-conditions="media:{(min-width:40em)}"> View on GoogleMaps
A condition consists of a monitor andan expected value for said monitor.
media:{(min-width:40em)}:{}
windowelementmediapointerconnectionavailable monitorswidth, heightvisible, width, heightquery, supportednear, fineany
Build your own custom monitors.
monitor/light.js{ trigger:{ 'devicelight':window }, test:{ 'min-lumen':function(data,event) { return data.expected <= event.value; } } }
light:{min-lumen:200}
Combine monitors in expressions.media:{…} and not (element:{…} or pointer:{…})Use the was operator to remember state.pointer:{was near}
.is('media:{(min-width:40em)}').then(…);.on('media:{(min-width:40em)}',function(){…});API
3. module reusabilityUniform configuration of module properties
Configuration is done through so called options.
ui/GoogleMap.jsdefine(function(){ var exports = function GoogleMap(element,options) { }; exports.options = {zoom: 10,type: 'map',key: null}; return exports; });
main.jsconditioner.setOptions({modules:{'ui/GoogleMap':{options:{key: '123ABC'}}}};
index.htmldata-module="ui/GoogleMap" data-conditions="media:{(min-width:350px)}" data-options="type:terrain"> View on GoogleMaps
Conditioner automatically mergesthese option objects.
{zoom: 10,type: ‘map’,key: null}{key: ’123ABC’}‘type:terrain’module website element
{zoom: 10,type: ‘map’,key: null}
{zoom: 10,type: ‘map’,key: ’123ABC’}
{zoom: 10,type: ‘terrain’,key: ’123ABC’}
new GoogleMap(element,{zoom: 10,type: 'terrain',key: '123ABC'});
loose endsPro’s, con’s and future developments
Fast development;Separate requests;Save CPU cycles;Pros
Separate requests;CPU cycles;It’s a framework;CONS
Currently working onvarious improvements.“Always looking forfeedback on the idea andexecution.”
Mr. Miyagi“Every piece of codeshould only have oneresponsibility.”