What I did in 2012? A review

For the sake of fun and keeping record; I'm sharing today "How I spent the year 2012!".

I developed many programming tools; experimented many new technologies like WebRTC as well as Canvas2D; developed many big private/public projects.

HTML Canvas Designer / try yourself
Canvas Designer is a drawing-tool which lets you draw any shape on a single drawing-surface; also it auto-generates appropriate Canvas 2D API relevant code for you in relative/absolute shortened/unshortened formats!
I designed it in 15-to-20 days....in May 2012.

HTML Curvature / try yourself
Curvature is a designer/tool for curving. It generates Canvas2D APIs relevant code in relative/absolute shortened/unshortened formats! It gives you full control over Bezier curves.
It was my first tool in 2012. I started working on it from 1st January; and I release it at 16 January 2012.

WebRTC Experiments & Demos / try yourself
In the last quarter of 2012; I started experimenting RTCWeb APIs. I did many realtime experiments:

---) WebRTC Text Broadcast / Chat using RTCDataChannel APIs
---) WebRTC File Broadcast / Sharing Files using RTCDataChannel APIs

1) WebRTC Screen Broadcasting!
WebRTC screen broadcasting: using Google Chrome experimental tabCapture APIs to broadcast screen over many peers.

2) WebRTC Video Broadcasting!
Allows you broadcast your video privately or publicly over many peers.

3) WebRTC Audio Broadcasting!
Allows you broadcast your voice privately or publicly over many peers.

4) WebRTC Experiment using WebSocket!
5) WebRTC Experiment using Pubnub!
6) WebRTC Experiment using socket.io!
7) WebRTC Experiment using XHR and ASP.NET MVC!

and there are many others. You can see all of them here.

HTML Canvas2D Experiments / try yourself
I experimented Canvas2D from June to August.

1) Bezier Curves and Coloring    1 . 2 . 3 . 4 . 5 . 6 . 7 . 8
2) Dragging/Moving shapes smoothly using Canvas 2d APIs
3) Flying Bird Experiment
4) Rocket Fire Experiment
5) Many Canvas2D Sketches

I tried CSS3 too!

Elance / view my elance profile
I started working on elance projects from 14th August 2012. Since then I got upto 30 unique clients from different areas of the world! It was a fun! Majority of projects were direct (and private); so you can't see them in the list.

There were some challenging projects for me. I’m a little bit crazy when I accept challenge. I can’t stop trying until I get success. For a project, I tried so many times I can’t remember; but I got success at the end!


UseMe: A comparative way of HTML5 features detection / try yourself


Just a fun!

Taxicab / work in progress
It is an online taxicab dispatching and booking as well as management system...it has following features:
1) An advance online booking system (anyone can book cars)
2) Some unique discounts and offers
3) An advance fares management system
4) Admin panel: manages the whole project
5) Operator panel: dispatches bookings and there are so many other features in this panel
6) An advance search
7) Postcodes database: around 2 million records in that database!!

and there are so many other things.
You can see my old taxicab projects (that I developed in 2010) in the apps section below.

Apps / try yourself
You can see all my apps here:


Dashing Quill Blog / another blog
I started this blog in 2011. In 2012, upto 7,600 unique people visited:

Click here to see full report of the year 2012 for Dashing Quill Blog
You can see what I posted there in 2012 here.

Most famous posts were:
1) Capturing WebCam using DirectShow.NET Library - Link
2) Javascript and CSS3 only sliding up/down transition effects - Link
3) Handling errors in ASP.NET MVC - Link

Google Sites / another blog
I posted two most famous articles in this blog...

1) ASP.NET MVC security and hacking: Defense-in-depth - Link
2) JavaScript Logical Operators: An Overview - Link

Note:
Upto 24655 unique people visited this blog in 2012.

The most famous posts were:
1) Absolute or Relative URL issues and the solution
2) Exploring CSP (Content Security Policy) using ASP.NET MVC
3) C# and wiki markup parsing

DTweet / an open source ASP.NET MVC project
It is an open source project. I developed it in 2011 and released in 2012.

In 2012, I started my career as open-source web developer. 2013 is coming with great opportunities.

I’m ready to do better! 

Save files on disk using JavaScript or JQuery!

You can save any file, or DataURL, or Blob on disk using HTML5's newly introduced "download" attribute.

Use cases:

1. Force browser to download/save files like PDF/HTML/PHP/ASPX/JS/CSS/etc. on disk
2. Concatenate all transmitted blobs and save them as file on disk - it is useful in file sharing applications

Microsoft Edge? (msSaveBlob/msSaveOrOpenBlob) https://msdn.microsoft.com/en-us/library/hh779016(v=vs.85).aspx

/**
 * @param {Blob} file - File or Blob object. This parameter is required.
 * @param {string} fileName - Optional file name e.g. "image.png"
 */
function invokeSaveAsDialog(file, fileName) {
    if (!file) {
        throw 'Blob object is required.';
    }

    if (!file.type) {
        try {
            file.type = 'video/webm';
        } catch (e) {}
    }

    var fileExtension = (file.type || 'video/webm').split('/')[1];

    if (fileName && fileName.indexOf('.') !== -1) {
        var splitted = fileName.split('.');
        fileName = splitted[0];
        fileExtension = splitted[1];
    }

    var fileFullName = (fileName || (Math.round(Math.random() * 9999999999) + 888888888)) + '.' + fileExtension;

    if (typeof navigator.msSaveOrOpenBlob !== 'undefined') {
        return navigator.msSaveOrOpenBlob(file, fileFullName);
    } else if (typeof navigator.msSaveBlob !== 'undefined') {
        return navigator.msSaveBlob(file, fileFullName);
    }

    var hyperlink = document.createElement('a');
    hyperlink.href = URL.createObjectURL(file);
    hyperlink.download = fileFullName;

    hyperlink.style = 'display:none;opacity:0;color:transparent;';
    (document.body || document.documentElement).appendChild(hyperlink);

    if (typeof hyperlink.click === 'function') {
        hyperlink.click();
    } else {
        hyperlink.target = '_blank';
        hyperlink.dispatchEvent(new MouseEvent('click', {
            view: window,
            bubbles: true,
            cancelable: true
        }));
    }

    (window.URL || window.webkitURL).revokeObjectURL(hyperlink.href);
}

Here is how to use above function:

var textFile = new Blob(['Hello Sir'], {
   type: 'text/plain'
});
invokeSaveAsDialog(textFile, 'TextFile.txt');

You can pass two arguments over "SaveToDisk" function:

1. file-URL or blob or data-URL - it is mandatory
2. file name - it is optional

Here is "SaveToDisk" function uses new syntax of "createEvent" API:

function SaveToDisk(fileURL, fileName) {
    // for non-IE
    if (!window.ActiveXObject) {
        var save = document.createElement('a');
        save.href = fileURL;
        save.download = fileName || 'unknown';
        save.style = 'display:none;opacity:0;color:transparent;';
        (document.body || document.documentElement).appendChild(save);

        if (typeof save.click === 'function') {
            save.click();
        } else {
            save.target = '_blank';
            var event = document.createEvent('Event');
            event.initEvent('click', true, true);
            save.dispatchEvent(event);
        }

        (window.URL || window.webkitURL).revokeObjectURL(save.href);
    }

    // for IE
    else if (!!window.ActiveXObject && document.execCommand) {
        var _window = window.open(fileURL, '_blank');
        _window.document.close();
        _window.document.execCommand('SaveAs', true, fileName || fileURL)
        _window.close();
    }
}

Here is "SaveToDisk" function uses old syntax of "createEvent" API:

function SaveToDisk(fileURL, fileName) {
    // for non-IE
    if (!window.ActiveXObject) {
        var save = document.createElement('a');
        save.href = fileURL;
        save.target = '_blank';
        save.download = fileName || fileURL;
        var evt = document.createEvent('MouseEvents');
        evt.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0,
            false, false, false, false, 0, null);
        save.dispatchEvent(evt);
        (window.URL || window.webkitURL).revokeObjectURL(save.href);
    }

    // for IE
    else if ( !! window.ActiveXObject && document.execCommand)     {
        var _window = window.open(fileURL, "_blank");
        _window.document.close();
        _window.document.execCommand('SaveAs', true, fileName || fileURL)
        _window.close();
    }
}

You can use FileReader too, to save "Blob" on disk:

function SaveToDisk(blobURL, fileName) {
    var reader = new FileReader();
    reader.readAsDataURL(blobURL);
    reader.onload = function(event) {
        var save = document.createElement('a');
        save.href = event.target.result;
        save.download = fileName || 'unknown file';

        save.style = 'display:none;opacity:0;color:transparent;';
        (document.body || document.documentElement).appendChild(save);

        if (typeof save.click === 'function') {
            save.click();
        } else {
            save.target = '_blank';
            var event = document.createEvent('Event');
            event.initEvent('click', true, true);
            save.dispatchEvent(event);
        }

        (window.URL || window.webkitURL).revokeObjectURL(save.href);
    };
}

Using "SaveToDisk" function

Force an image to be saved on disk instead of rendered by the browser:

SaveToDisk('https://muazkh.appspot.com/images/Curvature.PNG', 'image.png');

Force downloading of pdf files (it will NEVER allow any browser specific pdf-reader to render/open your pdf files):

SaveToDisk('https://muazkh.googlecode.com/files/Muaz-Khan-CV.pdf');

Even you can enforce following web-browser specific files to be downloaded/saved on the disk instead of rendered within the browser!

JavaScript SaveToDisk('/javascript-file.js')
HTML SaveToDisk('/html-file.html')
CSS SaveToDisk('/css-file.css')
ASPX SaveToDisk('/aspx-file.aspx')
PHP SaveToDisk('/php-file.php')
MVC SaveToDisk('/controller/action-method')

Following apps are using "SaveToDisk" function to save files/blobs/etc. on disk:

DataChannel.js A library for realtime data/file sharing using WebRTC!
RTCMultiConnection.js A library for realtime audio/video/screen/data and file sharing using WebRTC!
Group File Sharing Sharing files over multiple peer connections concurrently
RecordRTC A library for WebRTC-Developers to record audio and video streams

Specification

1. https://developer.mozilla.org/en-US/docs/DOM/document.createEvent
2. http://www.w3.org/TR/DOM-Level-3-Events/#events-Events-DocumentEvent-createEvent

function SaveToDisk(fileUrl, fileName) {
    var hyperlink = document.createElement('a');
    hyperlink.href = fileUrl;
    hyperlink.download = fileName || fileUrl;
    hyperlink.style = 'display:none;opacity:0;color:transparent;';
    (document.body || document.documentElement).appendChild(hyperlink);

    if (typeof hyperlink.click === 'function') {
        hyperlink.click();
    } else {
        hyperlink.target = '_blank';
        hyperlink.dispatchEvent(new MouseEvent('click', {
            view: window,
            bubbles: true,
            cancelable: true
        }));
    }

    (window.URL || window.webkitURL).revokeObjectURL(hyperlink.href);
}

Remember, "SaveToDisk" works fine on Firefox nightly and aurora.

To support Firefox general release; use same workaround that is used for IE in this post (with a little bit changes).

If Firefox fails:

It seems that firefox doesn't allows dispatching (click) event handlers if HYPER-LINK element is NOT in the DOM-tree.

Don't call "revokeObjectURL" outside the "onclick" handler.

You simply need to append HYPER-LINK element  into DOM; and remove it after "onclick" is fired:

function SaveToDisk(fileUrl, fileName) {
    var hyperlink = document.createElement('a');
    hyperlink.href = fileUrl;
    hyperlink.download = fileName || fileUrl;

    hyperlink.style = 'display:none;opacity:0;color:transparent;';
    (document.body || document.documentElement).appendChild(hyperlink);

    hyperlink.onclick = function() {
        hyperlink.parentNode.removeChild(hyperlink);
        (window.URL || window.webkitURL).revokeObjectURL(hyperlink.href);
    };

    if (typeof hyperlink.click === 'function') {
        hyperlink.click();
    } else {
        hyperlink.target = '_blank';
        hyperlink.dispatchEvent(new MouseEvent('click', {
            view: window,
            bubbles: true,
            cancelable: true
        }));
    }
}