prettify

baseline

Javascript i18n (internationalization)

The users of a web app should be able to select the interface language of preference. The default language is english and the developer has to give a list of the terms used along with the translations in all languages supported.
Each term can be
Each user selects a UI language that is stored in: ins.oUser.eUsrLang
Enumeration ins.enLng contains all the languages our system supports.
If a specified term is not supported, in the language that the user has chosen, then the english term is used.

Ajax C#

  • Visual Studio 2010/Solution Explorer
  • Solution.Add New Project.Visual C#.Web.ASP_NET Empty Web Application
  • Project.Add New Item.Visual C#.Generic Handler
aj.ashx
<%@ WebHandler Language="C#" Class="Aj" %>
using System;
using System.IO;
using System.Web;
public class Aj : IHttpHandler {
    public void ProcessRequest (HttpContext context) {
        Stream stIn = context.Request.InputStream;
        int nLen = (int)stIn.Length;
        byte[] aIn = new byte[nLen];
        stIn.Read(aIn, 0, nLen);
        System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
        string sData = enc.GetString(aIn);

        string[] aData = sData.Split();
        int nA = Convert.ToInt32(aData[2]);
        int nB = Convert.ToInt32(aData[3]);
        int nResult = nA + nB;  
        context.Response.CacheControl = "no-cache";
        context.Response.ContentType = "application/javascript";
        context.Response.Write("["+nResult.ToString()+"]");
    }
     public bool IsReusable {get {return false;}}
}

Ajax Javascript

How to call an ajax service from a web page using
  • Javascript
  • XMLHttpRequest
  • POST
The server side implementation using C# is in another post.

Javascript Stopwatch

I want to measure how long some processes are taking. So I wrote the Stopwatch class (click "Start", wait some seconds, click "Stop":
Class Stopwatch
"use strict";
ins.Stopwatch = function () {
    var dFr, dTo, that = this;
    this.nMilliseconds;
    this.nSeconds;
    this.nMinutes;
    this.nHours;
    this.nDays;
    var _bRun = false;
    this.bRun = function () { return _bRun; };
    this.Start = function () {
        _bRun = true;
        this.Reset();
        dFr = new Date();
    };
    this.Stop = function () {
        _bRun = false;
        if (!dFr) {
            return Reset();
        } else {
            dTo = new Date();
            return Calc();
        }
    };
    this.Reset = function () {
        dFr = dTo = null;
        this.nMilliseconds =
        this.nSeconds =
        this.nMinutes =
        this.nHours =
        this.nDays = 0;
        return 0;
    };
    this.toString = function (sFormat) {
        if (typeof sFormat !== "string") sFormat = "m:s.f";
        return sFormat.replace(/d/g, this.nDays.toString()).
            replace(/h/g, this.nHours.toString().PadLeft(2, "0")).
            replace(/m/g, this.nMinutes.toString().PadLeft(2, "0")).
            replace(/s/g, this.nSeconds.toString().PadLeft(2, "0")).
            replace(/f/g, this.nMilliseconds.toString().PadLeft(3,"0"));
    };
    var Calc = function () {
        if (dFr && dTo && dFr.getTime() < dTo.getTime()) {
            var nTime = dTo.getTime() - dFr.getTime()
            that.nMilliseconds = Math.round(nTime);

            that.nSeconds = Math.floor(that.nMilliseconds / 1000);
            that.nMilliseconds -= that.nSeconds * 1000;

            that.nMinutes = Math.floor(that.nSeconds / 60);
            that.nSeconds -= that.nMinutes * 60;

            that.nHours = Math.floor(that.nMinutes / 60);
            that.nMinutes -= that.nHours * 60;

            that.nDays = Math.floor(that.nHours / 24);
            that.nHours -= that.nDays * 24;
            return nTime;
        } else {
            return that.Reset();
        }
    };
    this.Reset();
};
if (typeof String.prototype.PadLeft != "function") {
    String.prototype.PadLeft = function (nLen, sPad) {
        if (typeof sPad !== "string") sPad = " ";
        if (typeof nLen !== "number") nLen = 2;
        var sResult = this;
        while (sResult.length < nLen) sResult = sPad + sResult;
        return sResult;
    };
}
Usage:
    var oSW = new i.Stopwatch();
    var oBtn, oDiv;
    window.onload = function () {
        oBtn = document.getElementById("btnFr");
        oDiv = document.getElementById("divResults");
        oBtn.onclick = ToggleSW;
    };
    var ToggleSW = function () {
        oBtn.disabled = true;
        if (oSW.bRun()) {
            oSW.Stop();
        } else {
            oSW.Start();
        }
        oBtn.innerHTML = oSW.bRun() ? "Stop" : "Start";
        oDiv.innerHTML = oSW.bRun() ? "" : oSW.toString("m:s:f");
        oBtn.removeAttribute("disabled");
    };

DOM prototype extensions

DOM should be OO. Fortunately it is to fix with javascript.
The problem is that the code becomes very verbose (and not elegant) when I want to create a part of a web page in code.
When I want to create a table in code, I create a documentFragment and call a MakeTable function:
DOM is not object oriented so for just one row and two cells:

HTML5 Forms browser support

In the first column you can test the TextBox described in the 3rd column.
The second column your browser claims support (or not) of the feature.
The first 6 rows test the new attributes and the following rows test the new input types.
You should try it with the latest Opera & Chrome.
<input placeholder="write here" />
<input autofocus  />
<input required  />
<input pattern="\d/\d/\d{4}"  />
<input list="lista" /><datalist id="lista">  
<option value="www.ins.gr" label="ins" />  
<option value="pkario.blogspot.com" label="blog" />  
<option value="www.insmoney.gr" label="insmoney" />  
</datalist>
<input multiple type="email" />
<input type="email"  />
<input type="url"  />
<input type="number" min="2" max="11" step="3"  />
<input type="range" 
    min="2" max="11" step="3" value="5"  />
<input type="tel"  />
<input type="time" min="11:00" max="22:00" step="30" />
<input type="date"  />
<input type="month"  />
<input type="week"  />
<input type="datetime"  />
<input type="datetime-local"  />
<input type="search" results="10" autosave="txtSearch" />
<input type="color"  />
27%
<progress value="27" max="100">27%</progress>
value is 70
<meter min="0" max="100" value="70"
low="-100" hight="100">value is 70</meter>
Web workers
var oWorker = new Worker("work.js");
Canvas
var oContext = document.createElement('canvas').getContext;
SVG
document.implementation.hasFeature(
"http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")
Offline apps
window.applicationCache;
localStorage
window.localStorage["sKey"]=sValue;
sessionStorage
window.sessionStorage["sKey"]=sValue;
Web SQL Database
window.openDatabase
indexedDB
window.indexedDB, mozIndexedDB, webkitIndexedDb
Web Sockets
window.WebSocket
Cross doc messaging
window.postMessage
File API
FileReader
Geo Location
navigator.geolocation
getters & setters
function Person(){
    var _sName;
}
Person.prototype = {
    get sName(){return this._sName;},
    set sName(sVal){this._sName = sVal;}
}
A set of words that is marked
A <mark>set of words</mark> that is marked
<time datetime="2010-08-20T17:00">5pm</time>
CSS entries:
 input:valid {background-color:#efe;}
 input:invalid {background-color:#fee;}
function to check validity:
function Check(oEvt) {
 oEvt = oEvt || event;
 var oEl = oEvt.target || oEvt.srcElement;
 return ("validity" in oInput)? oEl.validity.valid: null;
}

Table based infobox with css3

Table based infobox: Infotable html:
<table><thead><tr>
<th>Attribute</th><th>Value</th>
</tr></thead><tbody>
<tr><td>width</td><td>100px</td></tr>
<tr><td>title</td><td>text</td></tr>
<tr><td>colspan</td><td>4</td></tr>
<tr><td>rowspan</td><td>2</td></tr>
</tbody></table>

<table><thead><tr><th>
 Title
</th></tr></thead><tbody><tr><td>
<ul>
  <li>First element</li>
  <li>Second element</li>
  <li>Third element</li>
  <li>Fourth element</li>
  </ul>
</td></tr></tbody></table>

css (part of Reset.css included):
* { /*** Reset start ***/
 padding:0;
 margin:0;
 font-family:Tahoma,Verdana,Arial;
 font-size:100%;
}
ul {
 list-style:disc outside;padding-left:25px;
}
table {
 border-spacing:0;
 border:1px solid #666;
}
body {color:#333;}
/* Reset end */
table {
 margin:20px;
 width:10em;
 
 background:#ace;
 background: -moz-linear-gradient(top,#eff,#ace 7%, #ace 90%,#777 );
 background: -webkit-gradient(linear, left top, left bottom,  color-stop(0,#eff), color-stop(0.07, #ace), color-stop(1,#777));

 -moz-border-radius:.6em;
 border-radius:.6em;
 
 -webkit-box-shadow: .4em .4em .4em rgba(0,0,0,0.5);
 -moz-box-shadow: .4em .4em .4em rgba(0,0,0,0.5);
 box-shadow: .4em .4em .4em rgba(0,0,0,0.5);
}
 
table th {
 padding:.4em;
 text-align:center;
 border-bottom:1px #888 solid;
 background-color:transparent;
 text-shadow: .06em .06em .1em rgba(0,0,0,0.5);
}
table td {
 background:#fafafa;
 padding:.5em;
 border:1px #888 solid;
}
table tr:last-child td:first-child {
 -moz-border-radius-bottomleft:.5em;
 border-bottom-left-radius:.5em;
}
table tr:last-child td:last-child {
 -moz-border-radius-bottomright:.5em;
 border-bottom-right-radius:.5em;
}

Reset.css

My own Reset.css
Actually it contains Base.css as well. I don't see the reason for an extra Base.css
I don't test on IE7 (forget about IE6).
* {
 -moz-box-sizing:border-box;
}
/*upd: 20111020 ************************************/
* {
 box-sizing:border-box;
}
html, body, div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, cite, code,
del, dfn, em, img, ins, kbd, q, samp,
strike, strong, sub, sup,
dl, dt, dd,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
 margin:0;
 padding:0;
 border:0;
 font-weight:inherit;
 font-size:100%;
 font-style:inherit;
 font-family:inherit;
 border:1px none #000;
 background:transparent;
 vertical-align:baseline;
}
body {
 line-height: 1.2;
 color:#333;
}
body, select, input, textarea {
 font-family:Tahoma,Verdana,Arial,helvetica, Sans-Serif;
 margin:0;
}
article,aside,canvas,details,figcaption,figure,
footer,header,hgroup,menu,nav,section,summary { 
 display:block;
}
pre,code {
 font-family:Monospace;
}
html,body {
 height:100%;
}
table {
 border-collapse:collapse;
 border-spacing:0;
 /*width:100%;*/
}
th,td {
 border:1px solid #666;
 /*padding:.5em;*/
 vertical-align:top; 
}
caption {
 margin-bottom:.5em;
 text-align:center;
}
blockquote,q { quotes: "\201C" "\201D"; } 
blockquote:before { content: "\201C"; font-weight: bold; }  
blockquote:after { content: "\201D"; font-weight: bold; }

ol,ul {list-style-position:outside;padding-left:25px;}
ol {list-style-type:decimal;}
ul {list-style-type:disc;}
li:before {display:marker;marker-offset:1em;}

ins {text-decoration:underline;}
del {text-decoration: line-through;}
em {font-style:italic;}
h1 {font-size:200%;}
h2 {font-size:178%;}
h3 {font-size:159%;}
h4 {font-size:141%;}
h5 {font-size:126%;}
h6 {font-size:112%;}
h1,h2,h3,h4,h5,h6 {margin:1em 0;}
h1,h2,h3,h4,h5,h6,strong,th {font-weight:bold;}
mark {background-color:#ff9;}

abbr,acronym {
 border-bottom:1px dotted #000;
 cursor:help;
}
p,fieldset {margin-bottom:1em;} 
Credits:
Yahoo yui3 cssreset
Eric Meyer
HTML5 Reset.css
http://html5boilerplate.com/

Table Layout for web pages

You should never use tables for layout. You should use div. Having said that and having spent some time trying to force div to look like table I decided that enough is enough. If a table is what I need, a table is what I will use. What I need is a layout:
  • Header should cover the top of the window.
  • Header height should be determined by its contents.
  • Footer should cover the bottom of the window and resize by it. It must always be at the bottom of the window except when the contents of the page are more than that.
  • Left aside width should resize according to contents. The height should resize to full window or to contents (the largest of the two)
  • Right aside should behave like left aside.
The entire think should behave as a TABLE.
<table  id="tabLayout" role="presentation">
<tbody><tr id="trHeader">
  <td colspan="3">header</td>
</tr><tr>
  <td id="tdNav">nav</td>
  <td>main</td>
  <td id="tdAside">aside</td>
</tr><tr id="trFooter">
  <td colspan="3">footer</td>
</tr></tbody></table>
/*=== Reset start ====*/
html,body,table,tr,td {
 margin:0;
 padding:0;
 -moz-box-sizing:border-box;
 -o-box-sizing:border-box;
 -webkit-box-sizing:border-box;
 box-sizing:border-box;
}
table {
 border-collapse:collapse;
 width:100%;
}
html,body {
 height:100%;
}
/*=== Reset end ===*/
table#tabLayout {
 border-collapse:collapse;
 width:100%;
 height:100%;
}
#trHeader, #trFooter {
 height:1px;
}
#tdNav, #tdAside {
 width:1px;
}

Public key cryptography with GnuPG

Problem:

I want to send a document to a partner and be sure that no one else is going to read it.

I want to sign a document and send the signarure to a partner in a way he is sure that I signed it and he can prove it if need arises.

Solution:

Public key cryptography
key
Each person involved in the secure information exchange has two keys. One private key and one public key.
Both keys are just data (text) created by an application based on some information about the person (Name, email, passphrase).
Public key
A data file that you send to anybody asking. The public key can be used to
  • encrypt a document that can be decrypted only by your private key.
  • decrypt a document that was encrypted by your private key
To make the task easier there are key servers like hkp://keys.gnupg.net where you can store you public key so that anybody can find it without bothering you.
You can go to http://keys.gnupg.net/ and search for your friends (by name or email) to find if they have public keys stored there.
Private key
A data file that only you have. You can use it to:
  • Decrypt a document that was encrypted by your public key
  • Encrypt a document that can be decrypted only with your public key. Obviously anybody can decrypt the document but that way any receiptient is sure that the file was encrypted by you.
Digital Signature
A data file containing the ID (hash) of the document to be signed plus your ID (certificate),  encrypted by your private key.
Anyone can confirm that you signed the actual document (and you can not deny it) provided he has:
  • The actual document
  • The signature document
  • Your public key
Signed document
A document that is merged with your signature.
Digital Certificate
How can I be sure that the public key and the corresponding e-mail that I have is really yours?
If it is not then I will happily encrypt the document and send it to another person who can read it. Then I will find that all my nude pictures are on 4chan for everyone to enjoy (really doubt it).
The problem can be solved using certificates. Certificates are supplied by certificate servers that can confirm your identity matches your public key.
The open source solution is the certificates supported by a web of trust

Acquire a public key and a private key

  1. Go to GnuPG for Windows and download Gpg4win
  2. Install it
  3. Run GPA (GNU Privacy Assistant). It will prompt you for a new key. Go for it.
  4. It will ask for your real name and email. These are needed
    • So that is known who is signing what
    • To be registered in the public database hkp://keys.gnupg.net so that people can search and find your public key
    So be honest and give your real name and mail.
  5. It will ask for a passphrase. This is important. It is like a password but you are not supposed to change it now and then.
    So find a small phrase you will remember and intersperse with numbers or symbols (in a way you will remember).

Encrypt a document (to send to a partner).

  1. Find your partner's public key. You can ask him (better) or look at a server.
  2. Open GPA
  3. Import your partner's public key if you have not done already so. Keys⇒Import
  4. GPA⇒Toolbar⇒Files. File Manager application starts.
  5. Select the file and Encrypt it.

Sign a document

You want to send a document that there is no reason to be encrypted. The receiving party must have a way to prove that you sent the document, and it is not changed in any way.

  1. Run GPA
  2. GPA⇒Toolbar⇒Files. File Manager application starts.
Now in File Manager:
  1. File⇒Open. Select the file you want to sign.
There are a lot of stuff you can do, but most of them are trivial if you came this far:
  • Encrypt a file using a partner's public key.
  • Encrypt a file using your own public key (only you can decrypt it). Symmetric cryptography is a lot better for the task but you can do it if you insist.
  • Sign a file using your own private key.
  • Sign and encrypt a document using your own private key
  • Decrypt a document you received using your own private key
  • Verify the signature of a document you received using your partner's public key
If you don't want to use encrypted attachments for your encrypted documents you can
  • Set your mail agent format to "text only"⇒ Copy⇒Clipboard Encrypt⇒ Paste Encrypted to your mail program⇒send mail
  • If your mail agent is supported (Outlook, outlook express, thunderbird etc) then just install the addin and you can do it through your agent.
References