📜 ⬆️ ⬇️

Sausage.js - a library for turning any code into a call chain

I think everyone who at least once came across a Canvas met one not extremely convenient thing on their way. When working with Canvas to change any parameter of the context or method call, you have to refer first to the context, and then to the method / property - this is very annoying.

You always want this code:
var ctx = document.querySelectorAll('canvas')[0].getContext('2d'); ctx.fillStyle = '#eee'; ctx.strokeStyle = 'blue'; ctx.beginPath(); ctx.moveTo(10, 10) ctx.lineTo(100, 10) ctx.lineTo(100, 100) ctx.lineTo(10, 100) ctx.lineTo(10, 10) ctx.closePath() ctx.stroke() ctx.fill(); 

Turn into a chain:
 ctx .fillStyle('#eee') .strokeStyle('blue') .beginPath() .moveTo(10, 10) .lineTo(100, 10) .lineTo(100, 100) .lineTo(10, 100) .lineTo(10, 10) .closePath() .stroke() .fill(); 

Sausage.js - 1268 bytes (soon there will be less kilobytes) solving your problems.
“Luke, use __noSuchMethod__” - and you’ll say everything. But what about support for prehistoric browsers?
Anyone who is not indifferent to the Canvas, call chains and Lisp ask under the cat


Why Sausage and what has lisp?


This code (cross-browser, does the same thing as the first block) can be used by applying Sausage.js.
 //     (function(getContext, querySelectorAll, fillStyle, strokeStyle, beginPath, moveTo, lineTo, closePath, stroke, fill){ var canvasContext = $$(document)(querySelectorAll, 'canvas')(0)(getContext, '2d')(); $$(canvasContext, {fixedContext: true}) (fillStyle, '#eee') (strokeStyle, 'blue') (beginPath) (moveTo, 10, 10) (lineTo, 100, 10) (lineTo, 100, 100) (lineTo, 10, 100) (lineTo, 10, 10) (closePath) (stroke) (fill) (); }('getContext', 'querySelectorAll', 'fillStyle', 'strokeStyle', 'beginPath', 'moveTo', 'lineTo', 'closePath', 'stroke', 'fill')); 

Such chains are like sausages - that's why he called Sausage.js, the participation of a lisp here is of course none, just fans will appreciate the large number of parentheses :)
')

Why not emulate __noSuchMethod__?


With each change of context, I would have to run around all the methods and properties of the context and create a function for each - a long time and expensive, so I refused (I will do it later), but led to a similar view using function chains.

Initially, I didn’t plan to add __noSuchMethod__ at all, but then I decided that it would be right. And the name of the library Sausage now partially lost its meaning.

Browsers that support __noSuchMethod__ can work with Sausage in any convenient form:
 $$(canvasContext, {fixedContext: true}) (fillStyle, '#eee') (strokeStyle, 'blue') .beginPath() (moveTo, 10, 10) (lineTo, 100, 10) .lineTo(100, 100) (lineTo, 10, 100) (lineTo, 10, 10) (closePath) .stroke() .fill() (); 


Sausage.js usage examples


Example 1. Context switch

 context = {'foo': {'bar': '100500'}, 'bar': '888', 'zoo': /./}; //     {'foo': {'bar': '100500'}, 'bar': '888', 'zoo': /./} result = $$(context) ('foo') //     {'bar': '100500'} ('bar', -1) //   ('zoo') //    zoo (); //    - undefined ..   foo  / zoo 


Example 2. Fixed context

 context = {'foo': {'bar': '100500'}, 'bar': '888', 'zoo': /./}; //     {'foo': {'bar': '100500'}, 'bar': '888', 'zoo': /./} result = $$(context, {fixedContext: true}) ('foo') //     {'bar': '100500'} ('bar', -1) //   ('zoo') //    zoo (); //    - /./ 


Example 3. Function call - change context value

 context = {'foo': 1}; //     {'foo': 1} result = $$(context) ('foo', 1000) //     (function (context) { //      return '' + context.foo / 2; //    -  '500' }) ('length') //      (function (context) { return typeof context; //    -  'number' }) (); //    number 


Example 4. DOM wrapper

 result = $$(document) ('getElementById', 'div1') ('style') ('width', '100px') //   ({ //     /    height: '100px', color: 'red', border: 'solid 1px blue' }) (); // CSSStyleDeclaration Object 


Example 5. jQuery wrapper

 result = $$(jQuery) (['#div2']) //       - ,        ('css', {width: '100px', height:'100px', color: 'red', border: 'solid 1px blue'}) ('animate', {width: '200px', height:'200px'}) (); // jQuery 


Profiling


To start profiling, you need to connect a version with the profiler enabled and start profiling.
 $$.profile(); //    console && console.dir($$.profileEnd()); 

As a result, we get
 [anonymous function] Object { calls=2, time=0} [context call] Object { calls=1, time=0} [switching context] Object { calls=7, time=0} animate Object { calls=1, time=5} bar Object { calls=2, time=0} width Object { calls=1, time=0} 


Minuses


- For convenience, it is necessary to collect a dictionary of methods / properties (if you use sausage notation)
- Farewell autocomplete (if you use sausage notation)
- Challenges a bit slower
- In dotted notation, it is impossible to call the meotds / properties that the functions (length, call, apply, ...) functions cannot - $$([1,2,3]).length()(); can be - $$([1,2,3])('length')();

pros


- Due to the dictionary, the lack of a point and the use of chains - a significant reduction in the amount of code after compression
- Ability to cross-profile profile calls and count the number of calls
- Processing "Bundle"

Links


Live example jsfiddle.net/azproduction/LUXwY
Not packed version with comments (9168 bytes) sausage-js.googlecode.com/svn/trunk/Sausage.js
Packed version (1268 bytes) sausage-js.googlecode.com/svn/trunk/Sausage.min.js
Version with profiler sausage-js.googlecode.com/svn/trunk/Sausage-profile.js

Criticism, suggestions and suggestions are welcome.

UPD Added profiling description

Source: https://habr.com/ru/post/115357/


All Articles