Giter Site home page Giter Site logo

blog's People

Contributors

niloy avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

bsnayal

blog's Issues

Tracking mouse/flick speed

Tracking mouse/flick speed

Useful for implementing kinetic scrolling.

var timestamp = null;
var lastMouseX = null;
var lastMouseY = null;

document.body.addEventListener("mousemove", function(e) {
    if (timestamp === null) {
        timestamp = Date.now();
        lastMouseX = e.screenX;
        lastMouseY = e.screenY;
        return;
    }

    var now = Date.now();
    var dt =  now - timestamp;
    var dx = e.screenX - lastMouseX;
    var dy = e.screenY - lastMouseY;
    var speedX = Math.round(dx / dt * 100);
    var speedY = Math.round(dy / dt * 100);

    timestamp = now;
    lastMouseX = e.screenX;
    lastMouseY = e.screenY;

    console.log([speedX, speedY]);
});

Fetch binary data over XHR and convert to base64

To fetch binary data and convert to base64, do the following:

Fetch binary data by set responseType = "arraybuffer" for XHR. Make sure to
read response and NOT responseText.

After you have the response, I thought simply using btoa(response) will do the
base64 conversion. But it does not work.

Instead, a custom function needs to be used for reason I don't know. Below is the
function taken from here:

  function arrayBufferToBase64(buffer) {
    var binary = "";
    var bytes = new Uint8Array( buffer );
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
      binary += String.fromCharCode( bytes[ i ] );
    }
    return window.btoa( binary );
  }

Resource Loading Madness

Resource Loading Madness

In a ideal web world, a page would only download files that it requires. So,
if there are 5 js files and 2 web pages:

    Page1       Page2
    A.js        C.js
    B.js        D.js
    C.js        E.js

When Page1 is viewed, the browser would download A.js, B.js and C.js.
When Page2 is viewed, the browser would download C.js, D.js and E.js.
But making seperate calls for each file would make the page load very very slow.
So we concatante the sets into 2 files.

    Set1.js -> concat(A.js, B.js, C.js)
    Set2.js -> concat(C.js, D.js, E.js)

When Page1 is viewed, we load Set1.js and likewise for Page2. But it
appears that this kind of optimization is in direct conflict with another
type of optimization i.e. load only files that are needed.

When user first visits Page1, Set1.js is loaded which contains A,B and C.
Then when the user visits Page2, Set2.js is loaded. Here the code for
C.js is being loaded again. In a ideal case, we should load the subset
(D.js, E.js). But when you have multiple pages, detecting all possible subsets
is too complex and not feasible.

In conclusion, there are two types of optimization possible:

  • Concat all required files into a single file and load in browser
  • Only load files that are required for that page

And both optimization together is not possible. Choosing the concat way is
the only optimization that works for now as it makes page load fast. In some
distant future, where loading multiple files would not be so taxing
(SPDY), we can probably implement the second
optimization.

Converting to base64 using nodejs

function getBase64(filename) {
  let file = fs.readFileSync(filename, {encoding: "binary"});
  let buffer = new Buffer(file, "binary");
  return buffer.toString("base64");
}

Using nginx as proxy to NodeJS server running on localhost

Redirects all traffic coming to example.com to localhost:5555. Also redirects all http to https. Below is the nginx conf file.

server {
    listen 80;
    listen 443 ssl;

    server_name example.com;

    ssl_certificate /etc/ssl/ssl.crt;
    ssl_certificate_key /etc/ssl/ssl.key;
    ssl_session_timeout 5m;
    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://localhost:5555;
    }

    if ($ssl_protocol = "") {
        return 301 https://example.com$request_uri;
    }
}

If SSL is not required, the conf is even simpler, given below. Remove server_name if its the default server.

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://localhost:5555;
    }
}

Things I find wrong on the Web Platform

Things I find wrong on the Web Platform

Getting the damn bugs fixed

Browsers like any other software has bugs. And when you are developing using features that are relatively new, you tend to hit the bugs too often. The problem is, getting those bugs fixed. If you discovered a bug in IE, you can forget about getting it fixed because the IE team does not have a public bug tracker, typical Microsoft, we are talking about Firefox and Chrome here. Even after filing a bug, it would take years for the bug to actually get fixed... it sucks. The browser vendors have their own priorities and the problem faced by web developers seems of little importance. Just so you know am not bullshitting over here, check out these links:
https://bugzilla.mozilla.org/show_bug.cgi?id=818389
https://bugzilla.mozilla.org/show_bug.cgi?id=702508
This damn bug was reported in 2004 and still not fixed

Convincing standards bodies

Its good that the the web platform is open which in principle means anyone can contribute to it. But only a few people have access to modify it. These people are often employees of browser vendors or some other big corporation. And they dont care much about web developers either. While they are friendly most of the time, but being friendly doesnt help if you cant get the work done. Modifications to the spec seems to only happen when either they themselves feel the pain or their big multinational employers benefit from it. The needs of independent web developers is often just ignored. So in reality, the web is not truly open.

We should have switched to XHTML when we had the chance

I guess the conversation went something like this:

W3C: Guys, we feel we should switch the markup to XML because its more structured and can easily be defined by context-free grammer...
Browser vendors: Wait, What!!?? You want us to throw away our entire code because you guys feel HTML is a soup and requires special hacks to parse it? Fuck you!

Yep, its true that HTML has been a success but everyone had to pay a costly price for it... if not immediate, then over time. The guys at whatwg did a great job at defining the algorithm to parse HTML. But all they did was solve a problem they themselves created, they had a fucking obligation to solve it. Had they used XML, they would not need to write down a complex parsing algorithm, instead they could just be using any parse generator like Bison, YACC.

What is worse is, they convinced everyone that the problems in HTML are actually its features. For example, XML has draconian error handling, any error will simply stop parsing the page and throw error. HTML on the other hand is very...very forgiving, you can throw any kind of crap at it, it will manage to render something. This may seem like a good thing for newbie programmers, but more experience programmers will agree that this is a bad idea. It promotes novice programmers to write bad HTML without learning it simply because the browser renders it. Debugging that kinda messed HTML is a nightmare. And lowering the barrier to entry is also what gives everyone the impression that web developer are not real programmers.

In contrast, take JSON. JSON follows the draconian error handling. Did that stop JSON from becoming THE format for information interchange and configurations? JSON parsers were rapidly developed in other languages. Why? Because its so damn easy! You dont need to read a fucking spec to understand how to parse JSON. Easy implementation means lesser bugs. Lesser bugs means better software quality.

Resource loading

Optimization for the declarative use case

Take the for attribute as the example. If you create a label and input,
you can tie them up with the for attribute. But for requires string only.
So, if you are creating the label and input from javascript, you will then
have to think of a way to generate a unique string that can be used for the
for attribute. It would be much simpler if we can directly assign the
HTMLNode to the for property. I wish the code below would work:

var input = document.createElement("input");
var label = document.createElement("label");
label.textContent = "Full Name";
label.for = input;

The way removeEventListener works

Making a Triangle using div

Making a Triangle using div

I keep forgetting the technique, so writing it down here. This technique works
with borders.

This is how a box with 20px border will look like. Each border is given a
different color.

#box {
  border-left: 20px solid red;
  border-right: 20px solid blue;
  border-top: 20px solid black;
  border-bottom: 20px solid green;
  width: 20px;
  height: 20px;
}

border1

This is what happens when set the width and height of the box to zero.

#box {
  border-left: 20px solid red;
  border-right: 20px solid blue;
  border-top: 20px solid black;
  border-bottom: 20px solid green;
  width: 0;
  height: 0;
}

border2

We have 4 triangles. Now, its simply a matter of making a few of them
transparent, depending on the direction and the type of triangle we want.

If we make left and right borders transparent, and remove the top border,
we are left with a equilateral triangle pointing up.

#box {
  border-left: 20px solid transparent;
  border-right: 20px solid transparent;
  border-top: none;
  border-bottom: 20px solid green;
  width: 0;
  height: 0;
}

border3

If we only make the top and right borders transparent, we have a right
angled triangle.

#box {
  border-left: 20px solid red;
  border-right: 20px solid transparent;
  border-top: 20px solid transparent;
  border-bottom: 20px solid green;
  width: 0;
  height: 0;
}

border4

Just make both of them the same colors, okay!

Abstract class in Javascript

function AbstractClass() {
    if (Object.getPrototypeOf(this) === AbstractClass.prototype) {
        throw new Error("Sorry, you may not directly instantiate this class");
    }
}

Keyboard remapping

The following configuration remaps Caps Lock to Escape and Alt to Ctrl
on Ubuntu. Because programmers never really use the Caps Lock key. And remapping
Alt with Ctrl is so much convenient with common operations like Cut, Copy,
Paste etc.

Ubuntu 18.04

sudo apt install gnome-tweak-tool
gnome-tweaks

Tweaks > Keyboard & Mouse > Additional layout options.
Update Ctrl position and Caps Lock behaviour.

Open Settings > Keyboard > Navigation > Switch Applications = Ctrl + Tab.

Ubuntu

clear Lock
keycode 66 = Escape

clear control
clear mod1
keycode 37 = Alt_L Meta_L
keycode 64 = Control_L
add control = Control_L Control_R
add mod1 = Alt_L Meta_L

But now we need to enable Ctrl+Tab to switch applications. This can be done
on Ubuntu using the CompizConfig Manager. In Compiz, go to
Ubuntu Unity Plugin, Switcher Tab and configure the switcher keys.

Things I miss in Javascript

Things I miss in Javascript

Although I am happy to see JS getting extended and getting cool new features,
there are still many things I find missing that are really easy to implement. I
mean, its trivial to implement these missing features by JS itself. Anyways,
here is the list of stuff I find missing in Javascript in no particular order.

Functional way of looping based on a number

I wish this would work, its easy to implement it though but wish it came out of the box:

(5).times(function(i) {
  console.log(i);
});

Easy functional way to iterate an Object

Why cant I iterate an object using:

  var a = {foo: "bar"};

  a.forEach(function(value, key) {
    console.log(value, key);
  });

Instead, I have to write:

  Object.keys(a).forEach(function(key) {
    console.log(key, a[key]);
  });

Why are ES5 Object functions implemented as static functions?

Take Object.freeze for example, why do I need to write:

  Object.freeze(a);

Why cant I simply write:

  a.freeze();

Sure, I understand objects created using Object.create(null) wont have those
functions, but it isnt hard to have both static and non-static versions.

Array group function

I really like the array functions like map, filter, reduce introduced in
ES5. But, there is no function which could run over an array and group them
in categories. Such a function is really handy when you query a database using
a ORDER BY clause and you want to group the result set.

Example, say u have an array with some arbitrary numbers and you want to group
them based on even and odd.

  var a = [1, 9, 5, 7, 23, 32, 99, 150];

  var b = a.group(function(n) {
    return (n % 2 === 0) ? "even" : "odd";
  });

  console.log(b);
  // b = {
  //   even: [32, 150],
  //   odd: [1, 9, 5, 7, 23, 99]
  // };

It is simple to implement group function:

  Array.prototype.group = function(groupFunction) {
    var groupedArray = [];

    this.forEach(function(item) {
      var group = groupFunction(item);

      if (!(group in groupedArray)) {
        groupedArray[group] = [];
      }

      groupedArray[group].push(item);
    });

    return groupedArray;
  };

Preventing object property removal

Automating Form filling

Automating Form filling

So here is a fun way to fill forms with random values for testing them in
the development phase. Open up the javascript console and execute the
following code:

(function() {
    var elements = [];

    [].push.apply(elements, document.querySelectorAll("input[type=email]"));
    [].push.apply(elements, document.querySelectorAll("input[type=text]"));
    [].push.apply(elements, document.querySelectorAll("input[type=password]"));
    [].push.apply(elements, document.querySelectorAll("input[type=search]"));
    [].push.apply(elements, document.querySelectorAll("textarea"));

    elements.forEach(function(e) {
        e.value = "test_" + Date.now();
    });
}());

Simple script to automate form filling for fun and profit. Try it on the facebook login page.

Cleanliness is next to Godliness

Cleanliness is next to Godliness

We all have known this proverb since childhood but only recently I kinda understand its true meaning... at least thats what I think so. I always took this proverb literally, as in, a neat and clean environment and place. But it turns out, "cleanliness" can have meanings at multiple levels... the physical, spiritual.... and the software.

So we often hear we Indians being accused of hypocrisy when it comes to cleanliness. As in, we dont bother to keep our country clean, but when we travel abroad, we suddenly transform into highly cleanliness conscious people. While, this maybe true, but its not hypocrisy. The thing is, when you are standing in a place surrounded by litter all around, there is no motivation at all to carry that empty can in your hand till you find a dustbin. The good thing is, the reverse is also true. A person who usually doesnt care about keeping environment clean will also start caring about it since he would feel very, very guilty of littering a clean place. The point is... cleanliness promotes more cleanliness.

But the reason I am talking about cleanliness here is its amazing resemblance to software. If you have a code base that reeks of hacks and patches, its a very bad code base that smells at every corner. Since the code base is so bad, even good programmers who take pride in writing clean code will start writing bad code. Simply because the surrounding code is so bad, there is no motivation to write anything good. On the other hand, if you have a clean, well maintained code base, the not so good programmers will be afraid to introduce hacks into the code and spoil the code base. The clean environment will force them to learn the right ways to doing stuff. This way, both the individual programmer and the project benefits from a clean environment.

Memory leaking pattern in JS

Memory leaking pattern in JS

<!DOCTYPE html>
<html>
<head>
  <title>Memory leaking</title>
  <script src="main.js"></script>
</head>
<body>
  <button id="add">Add Node</button>
  <button id="remove">Remove Node</button>
  <div id="nodes"></div>
</body>
</html>

The following js code will not leak memory.

window.onload = function() {
  var i = 0;

  add.addEventListener("click", function() {
    var d = document.createElement("div");
    d.textContent = "Node";
    d.addEventListener("click", function() {
      alert(i++);
    });
    nodes.appendChild(d);
  });

  remove.addEventListener("click", function() {
    nodes.removeChild(nodes.firstChild);
  });
};

Even though the click handler on the div is refererring the variable i
in the closure, this is not going to create memory leaks. This is a feature
of the mark and sweep
garbage collection technique.

On the other hand, the following js will create memory leaks:

window.onload = function() {
  var i = 0;
  var arr = [];

  add.addEventListener("click", function() {
    var d = document.createElement("div");
    d.textContent = "Node";
    d.addEventListener("click", function() {
      alert(i++);
    });
    nodes.appendChild(d);
    arr.push(d);
  });

  remove.addEventListener("click", function() {
    nodes.removeChild(nodes.firstChild);
  });
};

We are keeping reference of the created div in the variable arr. So even
if they get removed from the DOM, the reference in the arr will prevent it
from garbage collected. One way to fix the problem is to remove the reference
from the array when we remove the element from DOM as well. The remove click
handler should be modified like this:

remove.addEventListener("click", function() {
  var index = arr.indexOf(nodes.firstChild);
  delete arr[index];
  nodes.removeChild(nodes.firstChild);
});

Makefile config for external bundles in browserify for faster builds

Here is the Makefile configuration:

EXTERNAL_JS_FILES=$(shell cat src/externalJSFiles)

app: build/external.js
    browserify $(patsubst %, -x %, $(EXTERNAL_JS_FILES)) -o build/app.js

build/external.js: src/externalJSFiles
    browserify $(patsubst %, -r %, $(EXTERNAL_JS_FILES)) -o $@

The externalJSFiles contain one file path per line:

./js/shims.js
./js/angular.js

Phonegap nuances

File path should not being with leading /

Something like <img src="/images/foo.png"> would work on a website but wont work on phonegap. Because while a browser looks for the image from the root of the website, phonegap looks for the file from the root of the filesystem. Also applies to url() in css files.

SVG requires fixed height and width

Give fixed height and width to SVG images or they might stop rendering.

Changing the application icon

While the docs says to put <icon src=...> in the config.xml to change the app icon, I couldn't make it to work. So for android, I just pasted the icon image at platforms/android/res/drawable which worked.

Unsigned APK files wont be installed on phones

Before distrubuting an APK file, it must be signed using jarsigner. Steps to generate and sign apk file here.

Things I learned & liked from Haskell

Currying

Every multi parameter function can be thought of accepting a single parameter
and returning a partial function. Example, consider a sum function which
accepts two numbers and returns the result.

sum(2, 3) -> 5 (Return type number)

But if only one argument is passed to the sum function, the return type would
instead be a function.

sum(2) -> Function(partial) which accepts 1 argument and returns a number

While I was aware of this technique in javascript, but never thought that the
concept could be generalized to any function.

Composing

Multiple functions can be composed together to make new functions. Example,

f = square . plus1

Assuming square squares a number and plus adds 1 to a number, the new
function f would perform these two operations on any given number. So the
following would be true:

f(2) = 5

The . is the compose operator in Haskell. The idea is to write very simple
functions and combine them together to make more complex functions.

Any binary function can be written in infix notation

Haskell doesn't have a mod operator like %. Instead there is a function
called mod which accepts two parameters. In Haskell, it can be written in
both infix and prefix mode. The following two statements are equivalent.

5 mod 2

mod 5 2

Infinite Lists

Writing [1..] is a unbounded list. Calling length on such a list will hang
the computer. But we can perform other array operations like head, take
without causing infinite recursion. Haskell evaluates the infinite list lazily
as much as it needs to.

Quickly check if a port is open on Linux

On Server run nc -l 9443 to run a simple server on port 9443.

On Client, run curl example.com:9443.

The server should display HTTP headers if the port is open.

Getting nested values in JSON that could be null

var a = {
  b: {
    c: {
      d: 1
    }
  }
};

console.log(getNestedValue(a, "b.c.d")); // 1
console.log(getNestedValue(a, "b.x.y")); // null

function getNestedValue(object, path) {
  var keys = path.split(".");
  var v = object;

  for (var i = 0; i < keys.length; i++) {
    var key = keys[i];
    v = v[key];

    if (v == null) {
      return null;
    }
  }

  return v;
}

Installing phonegap/cordova

Installing phonegap for android turned out to be a pain in the ass with its heavy dependency over java and related toolchain.

Make sure you have these installed

Make sure you have the proper PATHs added

ant, java, javac need to be globally accessible. Also, android which is part of Android SDK need to be available as well. So, make sure you have these paths added to your PATH as well:

*adt-bundle-windows-x86-20130917\sdk\platform-tools
*adt-bundle-windows-x86-20130917\sdk\tools

adt-bundle is the Android SDK.

Add these Environment variables

  • JAVA_HOME = C:\Program Files\Java\jdk1.7.0_60
  • ANDROID_HOME = adt-bundle-windows-x86-20130917\sdk

To create an android application, use the following command:
cordova build android

But to create the actual .apk file, go to the platforms/android/ directory and execute the command ant release. This will create the .apk file in the bin folder.

Problem on Windows

If you get error like Requirements check failed: CScript Error: Can't find script engine "JScript" for, install and run the application here.

Generating all possible arithmetic combinations

Recently, I read this very interesting blog post which
talked about combining the 4 basic arithmetic operators (+, -, *, /) with bunch of given numbers to
generate an answer. For example, how can the numbers {1, 2, 3, 4} be combined with the 4 basic
arithemetic operators to give the answer 24. One way is (1 + 2 + 3) * 4 = 24. There are other
ways as well. We can write a program that will generate all possible combinations. I decided to
write my own version using F#. The program works relatively well.

type Node =
    | Number of float
    | Addition of (Node * Node)
    | Subtraction of (Node * Node)
    | Division of (Node * Node)
    | ProductList of Node list

type Nodelist = Node list

let combineProduct (n1: Node) (n2: Node) : Node =
    match (n1, n2) with
    | (Number 0.0, _) -> Number 0.0
    | (_, Number 0.0) -> Number 0.0
    | (ProductList p1, ProductList p2) -> ProductList (p1 @ p2)
    | (ProductList p1, p2) -> ProductList (p2 :: p1)
    | (p1, ProductList p2) -> ProductList (p1 :: p2)
    | (_, _) -> ProductList [n1; n2]

let combineDivision (top: Node) (bottom: Node) : Node =
    match (top, bottom) with
    | (_, Number 1.0) -> top
    | (_, _) -> Division (top, bottom)

let combineTwoNodes (n1: Node) (n2: Node) : Nodelist =
    [
        Addition (n1, n2)
        Subtraction (n1, n2)
        Subtraction (n2, n1)
        combineProduct n1 n2
        combineDivision n1 n2
        combineDivision n2 n1
    ]

let rec pickAtIndex (xs: 'T list) (index: int) : 'T * 'T list =
    match index with
    | 0 -> (List.head xs, List.tail xs)
    | _ ->
        let head = List.head xs
        let tail = List.tail xs
        let e, rest = pickAtIndex tail (index - 1)
        (e, head :: rest)

let rec permuteNodes (nodes: Nodelist) : Nodelist =
    match nodes with
    | [] -> []
    | [n] -> [n]
    | [a; b] -> combineTwoNodes a b
    | nodes ->
        let n = [1 .. (nodes.Length - 1)]
        let a = n |> List.map (pickAtIndex nodes)
        a |> List.collect (fun (x, y) -> (permuteNodes y) |> List.collect (combineTwoNodes x))
        
let encloseInBrackets str = "(" + str + ")"

let rec str (node: Node) : (string * float) =
    match node with
    | Number n -> (string n, n)
    | Addition (n1, n2) -> 
        let str1, value1 = str n1
        let str2, value2 = str n2
        (str1 + "+" + str2 |> encloseInBrackets, value1 + value2)
    | Subtraction (n1, n2) -> 
        let str1, value1 = str n1
        let str2, value2 = str n2
        (str1 + "-" + str2 |> encloseInBrackets, value1 - value2)
    | Division (n1, n2) ->
        let str1, value1 = str n1
        let str2, value2 = str n2
        (str1 + "/" + str2 |> encloseInBrackets, value1 / value2)
    | ProductList p ->
        let a = p |> List.map str
        let str = a |> List.map fst |> String.concat "*" |> encloseInBrackets
        let value = a |> List.map snd |> List.reduce (*)
        (str, value)

[1.0; 2.0; 3.0; 4.0]
    |> List.map Number
    |> permuteNodes
    |> List.map str 
    |> List.filter (fun (s, v) -> v = 24.0)
    |> List.map (fun (s, v) -> s + "=" + (string v))
    |> String.concat "\n"
    |> printfn "%s"

Javascript Generators

Javascript Generators

So a few days back, I was trying to write a command line based application in
nodejs which involved lots of async queries to database. Writing async queries
seemed simple enough at first, but as the nesting of the async calls grew,
the complexity of the code went up exponentially and the readability just went
out the window. The situation became so bad, I decided its not worth it to write
such messed up code in nodejs and gave up. Then I noticed that Chrome got an
update. I looked whats new in the version and there it was... Javascript
Generators in V8
has landed in stable.

I was a bit disappointed at first that it didnt solve the async problem out of
the box. Instead, it provides you with the necessary tools to solve it yourself.
Similar to how classes are done in JS. But I guess, the flexibilty also gives
more power and control.

To use javascript generators in Chrome, you have to enable it by going to
chrome://flags#enable-javascript-harmony.
To use generators in Node, you have to pass --use_strict --harmony flags
while invoking the script.

As a simple example to demonstrate the power of generators, lets define a
harmless async function.

    function asyncAdd(a, b, callback) {
        setTimeout(function() {
            callback(a + b);
        }, 500);
    }

The function will add two numbers and will return the result in the callback.
So, say we want to add 1 + 2 + 3 + 4. The code will be like this:

    var result = 0;

    asyncAdd(1, 2, function(r) {
        asyncAdd(r, 3, function(r) {
            asyncAdd(r, 4, function(r) {
                result = r;
            });
        });
    });

Damn horrible mess also known as The Pyramid of Doom. Generators can be used
here to turn async function calls into sync and make the code linear. Using
generators, we can write the code as:

    function suspend(generator) {
        var g = generator(function(result) {
            g.next(result);
        });

        g.next();
    }

    suspend(function* (resume) {
        var r = yield asyncAdd(1, 2, resume);
        var s = yield asyncAdd(3, 4, resume);
        var z = yield asyncAdd(r, s, resume);

        console.log(z); // 10
    });

This is really a pattern of writing code. As I mentioned above, the ability to
convert async functions into sync is not provided out of the box. The suspend
function above adds that magic. To understand why/how the suspend function works,
we will first need to understand how generators work, which can be a bit
confusing at first. Google up Javascript Generators, people have already
written articles explaining them. Generators have been in Firefox for quiet
some time now. Even NodeJS modules are avaliable that use generators.

Here a working JSFiddle example to generators: http://jsfiddle.net/gT2Fy/

IE11 problem with custom data attributes and CSS

IE11(and maybe lower version too) has problems with custom data-* attribute
and css. If you are using custom data attribute to hook css and then change the
value of the attribute at runtime, the CSS that is to be applied wont get
applied.

Fiddle showing the problem: http://jsfiddle.net/z8a38wd2/

On IE11, nothing will happen, but on other browser, a blue or red square will
appear. To fix the problem, you have to go back to using class.

Get nested property from an Object

Get nested property from an Object:

f(null, _) = null
f(a, []) = a
f(a, x:xs) = f(a[x], xs)
function getProp(obj, propStr) {
  const arr = propStr.split(".");

  function get(obj, propArr) {
    if (obj == null) {
      return null;
    } else if (propArr.length === 0) {
      return obj;
    } else {
      const head = propArr[0];
      const tail = propArr.slice(1);
      return get(obj[head], tail);
    }
  }

  return get(obj, arr);
}

// Usage:
const obj = {
  a: {
    b: 1
  }
};

console.log(getProp(obj, "a.b"));

The Knob component

Creating the Knob component

The working example can be seen here

The first step was to find a good mockup for the Knob. I found it here:
UIParade. I could not find
the psd for the image, so I just copied the image.

The next step was to remove the arrow on the image, since the position of the
arrow depends on the value of the knob. So I opened the image in Gimp and used
the clone tool to remove the arrow. In the component, am creating the arrow
using pure css. Also, there is a lot of empty space on the left and right side
of the knob image, so I croped it and made it smaller. The final image looked
like this:

Next, I need to put this in a html page. So the basic strucure I decided to use
is 3 div stacked on top of each other. The bottom most div will have the knob
image as background-image. The middle div will be a transparent div with just
the arrow. And a third empty div which will simply server the purpose of
receiving input(mouse and wheel).

-------------        -------------      -------------  
|           |        |           |      |           |  
|           |        |           |      |           |  
|           |        |         ->|      |           |  
|           |        |           |      |           |  
|           |        |           |      |           |  
-------------        -------------      ------------- 
   Div 1                  Div 2              Div 3
 (Knob Image)       (Contains arrow)     (Input reciever)

Now, when you want to change the position of the arrow, you simply use
css transform: rotate on div2. I decided that the knob component will
always return value in the range 0 - 1, just like Math.random. This
reduces calculation complexity of the component and is still generic enough
to be used with any number range.

If you look at the image, at the max, you can turn the knob to about 270 degrees.
This means, any value between 0-1 needs to be mapped to 0-270 degrees. The
formula is simple:

degrees = value * 270

So, say the value is 0.5, we put transform: rotate(135deg) css on Div2. To
make the rotation a smooth animation, we simply add transition: transform 0.25s
css on it. These steps happen when we set the value of the knob programatically.
The knob value setter implements this code. The code looks like this:

var deg = this.value * this.MAX_KNOB_ANGLE;
this.arrowContainer.style.transform = "rotate(" + deg + "deg)";

Now comes the tricky part, when user changes values of the knob using mouse.
The user will hold the arrow and drag it in a circlular motion. As it turns out,
this is really very simple with some basic geometry. This is where Div3 comes
into the picture. I have setup the mousedown, mousemove and mouseup on
div3. Whenever the user clicks and drags the mouse, we simply need to measure
the angle the mouse makes with the x-axis. The x-axis is at the center of div3.
Refer the image below:

knob

The angle (theta) is calculate as:

angle = Math.atan2(mousey - centery, mousex - centerx)

Once we get the angle, converting it to value is trivial using the formula we
described earlier.

value = angle / 270

Once we get the value, we simple call the knob value setter which in turn
rotates div2. This completes the illusion of rotating the Knob.

The entire code can be see here.

Merge objects in ES5

How to merge objects in ES5 world when the object contains getters and setters:

function merge(target, source) {
  for (var i in source) {
    var d = Object.getOwnPropertyDescriptor(source, i);
    Object.defineProperty(target, i, source);
  }

  return target;
}

Javascript Extendable Classes

Javascript Extendable Classes

So, here is a fun way to create classes and extend them in js. We all know the
standard way of creating & inheriting classes. Here, lets look at the
extendable function.

function extendable(parent, properties) {
  var proto;

  if (arguments.length === 1) {
    proto = {};
    properties = parent;
  } else {
    proto = parent.prototype;
  }

  function child() {
    if ("init" in properties) {
      this.init.apply(this, arguments);
    }
  }

  child.prototype = Object.create(proto);

  for (var i in properties) {
    child.prototype[i] = properties[i];
  }

  child.extend = extendable.bind(null, child);

  return child;
}

Now, any class created using the extendable function will have a function
extend that can be used to create the child class. The line of code that
does the trick is:

child.extend = extendable.bind(null, child);

So, say we want to create a base class Rectangle and its child class Square.
The code would be:

var Rectangle = extendable({
  init: function(l, b) {
    this.l = l;
    this.b = b;
  },

  area: function() {
    return this.l * this.b;
  }
});

var Square = Rectangle.extend({
  init: function(l) {
    Rectangle.prototype.init.call(this, l, l);
  },

  perimeter: function() {
    return 2 * (this.l + this.b);
  }
});

var s = new Square(2);
console.log(s instanceof Square);     // true
console.log(s instanceof Rectangle);  // true
console.log(s.area());                // 4
console.log(s.perimeter());           // 8

Simple & Sweet.

Implementing 'split' in Haskell

String -> String -> [String]

-- skips the first 'count' elements from array and returns the rest
skip count str = snd(splitAt count str)

-- returns the index of first occurance of 'patt' inside 'str', 'acc' is
-- initilized with 0, used internally.
pos str patt acc
  | str == [] = -1
  | take pattLength str == patt = acc
  | otherwise = pos (tail str) patt (acc + 1)
  where pattLength = length patt

-- break the given string 'str' into 'left' and 'right' portions based on the
-- position of 'patt' occuring inside it. 'left' becomes part of the output
-- array, 'right' is recursively fed to 'split'.
split str patt
  | p == -1 = [str]
  | otherwise = left : split right patt
  where p = pos str patt 0
        parts = splitAt p str
        left = fst parts
        right = skip (length patt) (snd parts)

Creating Inheritance Diagrams for better documentation

Creating Inheritance Diagrams for better documentation

A typical large scale software is often broken using classes. These classes
follow complex inheritance patterns. Understanding the inheritance of classes
gives a better understanding of the software. So in this post today, we will
explore how to automatically create Inheritance diagrams from the code
directly.

For the demonstration, lets pick THREE.js
which is a popular JavaScript library for creating 3D graphics in the browser.
Every piece of functionality in the library has been neatly wrapped in classes.

The first thing we need to do is download the source code. THREE.js already
provides production ready code here.
This single file contains all the classes in the project. This is especially
helpful because we don’t need to iterate over multiple folders to look for
class definitions.

In THREE.js, all inheritance is done using Object.create. For example,

THREE.Camera.prototype=Object.create(THREE.Object3D.prototype)

This means, the class Camera inherits from Object3D. We can use grep
and find out all such statements.

grep -o "THREE\.[^.]*\.prototype=Object\.create([^)]*)" three.min.js

The -o tells grep to only display matching portion instead of full line.
Executing the command above generates output like this:

THREE.Camera.prototype=Object.create(THREE.Object3D.prototype)
THREE.OrthographicCamera.prototype=Object.create(THREE.Camera.prototype)
THREE.PerspectiveCamera.prototype=Object.create(THREE.Camera.prototype)
THREE.Light.prototype=Object.create(THREE.Object3D.prototype)
THREE.AmbientLight.prototype=Object.create(THREE.Light.prototype)
THREE.DirectionalLight.prototype=Object.create(THREE.Light.prototype)
THREE.HemisphereLight.prototype=Object.create(THREE.Light.prototype)
THREE.PointLight.prototype=Object.create(THREE.Light.prototype)
THREE.SpotLight.prototype=Object.create(THREE.Light.prototype)
THREE.BinaryLoader.prototype=Object.create(THREE.Loader.prototype)
THREE.JSONLoader.prototype=Object.create(THREE.Loader.prototype)
...

We can pipe this output to the following sed command:

sed 's/THREE\.\([^.]*\)\.prototype=Object\.create(THREE\.\([^.]*\)\.prototype)/\t\2 -> \1/'

Which will generate the following output:

Object3D -> Camera
Camera -> OrthographicCamera
Camera -> PerspectiveCamera
Object3D -> Light
Light -> AmbientLight
Light -> DirectionalLight
Light -> HemisphereLight
Light -> PointLight
Light -> SpotLight
Loader -> BinaryLoader
Loader -> JSONLoader
...

We need to generate this particular format because this is understood by the
graphviz library. graphviz is a Graph Visualization
Software that can create graph/tree images from input text files. On Ubuntu,
installing it is as simple as:

sudo apt-get install graphviz

Note: dot is the actual name of the executable that generates the graph. But,
it comes under the graphviz package.

The final input to dot should be this:

digraph tree {
    Object3D -> Camera
    Camera -> OrthographicCamera
    Camera -> PerspectiveCamera
    Object3D -> Light
    Light -> AmbientLight
    Light -> DirectionalLight
    Light -> HemisphereLight
    Light -> PointLight
    Light -> SpotLight
    Loader -> BinaryLoader
    Loader -> JSONLoader
}

The code above is also known as the DOT language.

Assuming the dot commands is stored in a file called tree.gv, execute the
following command:

dot -Tsvg -othree.tree.svg tree.gv

This command will generate the tree output in SVG format in the file
three.tree.svg.

Putting it all together in a shell script:

echo "digraph tree {" > /tmp/tree.gv
grep -o "THREE\.[^.]*\.prototype=Object\.create([^)]*)" three.min.js|\
sed 's/THREE\.\([^.]*\)\.prototype=Object\.create(THREE\.\([^.]*\)\.prototype)/\t\2 -> \1/'\
>>/tmp/tree.gv
echo "}" >> /tmp/tree.gv
dot -Tsvg -othree.tree.svg /tmp/tree.gv

And you are done. Ofcourse, this idea is not limited to inheritance diagrams. One
can plot a graph of various function calls being made by a certain class. Or
the entire site diagram where each node is a page and each edge represents a
hyperlink. The possibilities are really endless!

Turing completeness for Typescript Type language

Simple proof of Turing completeness for Typescript Type language

type True = true;
type False = false;

type Nand<B1, B2> = B1 extends True ? (B2 extends True ? False : True) : True;

The code above implements a NAND gate using Typescripts type language. What this means is, the compiler can evaluate the result in the editor itself without actually executing the code. For example:

let a: Nand<True, True>;      // type a = False
let b: Nand<True, False>;    // type b = True

You don't need to execute this code, just hover over the variables a and b in your editor, the type of the variable will be evaluated by the compiler.

Why does this prove Turing completeness?

NAND is a universal gate which is the basis of all digital computers. Which is to say any computable function can be implemented using the type language, for example to calculate the factorial of a number or solve sudoku puzzle. That does not mean it is going to practically feasible to do so... but theoretically possible.

Can we similarly implement other gates?

Yes, below are implementation of NOT and AND using the above NAND gate.

type Not<B> = Nand<B, B>;

type And<B1, B2> = Not<Nand<B1, B2>>;

Any other interesting links?

https://www.nandgame.com/
The above link teaches the fundamentals of digital computer using a game which is the inspiration for the proof.

https://github.com/eamonnboyle/sudoku-type-solver
The above link implements a sudoku solver using Typescript Type language.

Creating SVG/MathML from JS

Creating SVG/MathML from JS

Always use createElementNS.

For SVG, the namespace URI is http://www.w3.org/2000/svg.
For MathML, http://www.w3.org/1998/Math/MathML.

Some api that work with HTML wont work with these elements. For example, when setting a class in HTML, ele.className = "abc" works, but it wont work for svg & mathml.

Instead use setAttribute.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.