2011年6月13日月曜日

Internet Explorer 10 Platform Preview 1レビュー

 IE10 PP1は、「Internet Explorer Test Drive」というサイトからダウンロードできる。IE9と共存できるため、既存の環境に影響を与えることなく、操作を試せる。ただし、IE8と同時に動かすとエラーが出ることがあるため、注意が必要だ。

 今後、8〜12週ごとに「Platform Preview」と呼ばれる、プレビュー・バージョンを公開していく予定である。

 なお、IE10 PP1には、基本的なブラウズ機能のみが提供されており、セキュリティ機能を含むほとんどの機能が省略されている。そのため、日常的に使用する場合は、セキュリティ・リスクがあることを理解したうえで利用してほしい。

■ 1. ネイティブHTML5
 MIX11のキーノートの中で、Windows上での「ネイティブHTML5」サポートという話があった。

 これを聞いて思い出したのが、かつてIE4がWindowsと統合して、「アクティブ・デスクトップ」という機能を実現しようとしたことである。デスクトップをWebページにしてインターネットと統合するというものであった。現在でも、デスクトップ上に配置できるガジェットや、IE9で追加されたタスクバー上へのピン留めや、ジャンプ・リストの表示(次の画面を参照)などにより、デスクトップとIEの統合は実現されている。またIE9では、GPUによるハードウェア・アクセラレーションが実装されており、ハードウェアによるWebページの描画(ハードウェア・アクセラレーション)も行われるようになっている。


ピン留め機能によりWebページをタスクバーに統合した例
FacebookやHotmailなどのサイトをタスクバーに登録して、それらのサイトの(タスクバー上の)アイコンを右クリックすることで、このようなメニューを表示できる。
 では、IE10の「ネイティブ」というのは、何を指しているのだろうか?

 先日公表されたWindows 8の新しいUIでは、Windows Phone 7ですでに採用されているMetro(メトロ)デザインがHTML5で実現されている。最終的にこのUIが標準になるのかどうかは分からないが、以前、アクティブ・デスクトップで実現しようとしていた、OSとブラウザの統合を進めていくと思われる。また、将来的に(IEへの)HTML5の実装が進むと、ファイルやDB(データベース)へのアクセスが実装されるため、「クライアント・アプリケーションとWebアプリケーションの差がほぼなくなる」と予想される。デスクトップとIEが統合されることにより、エンド・ユーザーからは両者の区別がほとんどつかなくなることも考えられる。

 IE10がリリースされる時点で、どこまで実現されるかは分からないが、Windowsとの統合により、よりリッチなユーザー・エクスペリエンス(UX)が実現できることを目指していると思われる。

■ 2. サポートされる環境

 IE10 PP1は、Windows 7のx86または、x64環境で動作する。Windows Vistaには対応していないので注意が必要だ。

 IE9では、「ハードウェア・アクセラレーションに対応していない」という理由でWindows XPがサポート対象外になったが、IE10では、Windows Vistaがサポート対象外になり、Windows 7以降のサポートになる予定である。サービスパック2を適用したWindows Vistaのサポート期限が2012年4月10日であるため、IE10のリリースはその後になるのではないかと考えている。

 「サポート対象が減る」という話だけではなく、「サポート対象が増える」という話もある。MIX11のキーノートの中では、ARMプロセッサ上で動作するIE10が紹介されていた。ARMプロセッサといえば、携帯電話やタブレット端末など、中小型の端末で採用されているプロセッサであり、2011年1月にラスベガスで開催された家電展示会のCESでは、次期WindowsがARMプロセッサをサポートすることを発表している。ARMプロセッサのサポートは、次期Windowsを見据えてのことと予想される。

■ 3. インストール

 IE10は、Internet Explorer Test Driveで公開されている。

IE9かIE10かを選択できるため、[IE10 Platform Preview 1]の[Download Preview 1]ボタンをクリックする
インストール先のフォルダは「C:\Program Files\Internet Explorer Platform Preview」(x64の場合は、「Program Files」部分が「Program Files(x86)」になる)であるため、既存のIEに影響を与えることなくインストールすることが可能だ

 このように、気軽にインストールできて、既存の環境にも影響を与えないため、あまり心配せずに試してほしい。

■ 4. ユーザー・エージェント文字列

 Webサーバに送られるユーザー・エージェント文字列の変化について確認していこう。まずは、IE9では、以下の文字列が使われている。

Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
IE9のUser-Agent
バージョンを見ると、MSIEは「9.0」、Tridentは「5.0」になっている。
 IE10でも、大きな変更はなく、以下のようになっている。

Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)
IE10のUser-Agent
MSIEのバージョンとTridentのバージョンが上がっていることが分かる。
 同じくJavaScriptコード上で取得できるバージョンも確認してみよう。次のコードはそのコード例である。

alert(navigator.appVersion);
// IE9上での結果:
// 5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; NET4.0C; .NET4.0E;)
alert(navigator.userAgent);
// IE10上での結果:
// navigator.userAgent:Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E;)
JavaScriptでブラウザバージョンを取得した結果
JavaScriptのユーザー・エージェント文字列もバージョンが上がっている。
 このように、Webサーバに送られるものも、JavaScriptコードで取得できるものも、MSIEのバージョンが「10.0」に上がっているのと、ブラウザのエンジンであるTridentが「6.0」に上がっていることが分かる。1つ注意点としては、サーバサイドのアプリケーションで、ブラウザのバージョンを「MSIE 1」のような文字列のパターン・マッチングで比較している場合、IE 1.0と認識してしまわないように、いまのうちに確認しておくことをお勧めする。


■ 5. メニュー

 ここでは、メニューバーの各機能について解説していこう。なお以下では、メニューバー上に表示されているメニュー項目を「メニュー」と表記する。

● 5-1. [Page]メニュー

 (メニューバーの)[Page]メニューでは、次の画面のように、Webブラウザの基本的な機能が提供されている。


[Page]メニュー
 ここでは、特に知っておく必要があるであろう、[Open]と[Allow websites to track your location]というサブメニュー項目について解説しよう。

○[Open]サブメニュー

 IE10 PP1では、アドレスバーが提供されていないため、特定のページを開くためには、[Page]メニューの[Open]サブメニューをクリックして、下に示す[Open Web Page]ダイアログからURLを指定する必要がある。


[Open Web Page]ダイアログ
このダイアログで開きたいページのURLを入力する。
 特定のページを開くためには、「Open Web Page」ダイアログでURLを入力する必要がある。

○[Allow websites to track your location]サブメニュー

 このサブメニュー(オン/オフ可能)は、ユーザーの現在位置を通知しないオプションである。このオプションは、次の画面に示すようにIE9でも[インターネット オプション]ダイアログの[プライバシー]タブの中に、[Web サイトによる物理的な位置の要求を許可しない]チェックボックスとして存在している、


IE9の[インターネット オプション]ダイアログの[プライバシー]タブ
 IE10 PP1では、まだ[インターネット オプション]ダイアログが提供されていないため、[Page]メニューに用意されている。

 このオプションをオフ(=許可しない)に設定して、Googleマップの現在地ボタン(=人型アイコンの上の○ボタン)を押してみると、現在地に移動できないことが分かる。


Googleマップで現在地ボタンをクリックした結果
現在地に移動しない。
 現在地の通知を許可しない設定にすると、現在地ボタンをクリックしても、現在地に移動されない。また、ページ上部に黄色い帯が出ており、なにかメッセージを表示しようとしているように見えるが、中にはメッセージが表示されていない。

 ちなみに、IE9のデフォルト設定(現在地の通知を許可)でも、以下のように通知バーが表示されて、位置情報の通知を許可するかどうかを選択できるようになっている。


IE9で現在地を送信するかどうかの確認を行う通知バー
IE9で現在地ボタンをクリックすると、通知バーが表示される。
 このようにIE9では通知バーで確認されるが、IE10 PP1ではこのようにリッチなUIが提供されていないため、[Page]メニューで、許可するかどうかのみが選択できるようになっている。

● 5-2. [Debug]メニュー

 [Debug]メニューには、その名のとおりデバッグに必要なサブメニューが用意されている。

○[F12 developer tools]サブメニュー

 IE9でも提供されている「F12 開発者ツール」だが、いまのところIE9とほぼ同じ形で提供されているため、ここでは解説を割愛する。

○[Force IE5 Document Mode]サブメニュー
○[Force IE7 Document Mode]サブメニュー
○[Force IE8 Document Mode]サブメニュー
○[Force IE9 Document Mode]サブメニュー
○[Force IE10 Document Mode]サブメニュー

 これらのサブメニューでは、ページを描画するエンジンを変更できる。ドキュメント・モードの切り替えについては、IE9でもすでに提供されており、「Internet Explorer 9正式版レビュー」で解説されているため、詳細はそちらを参照してほしい。

○[Reset Document Mode to page default]サブメニュー

 上記の[Force IEx Document Mode]サブメニューでは、ドキュメント・モードを強制して、描画エンジンを切り替えられる。このサブメニューでは、一度変更した描画エンジンをデフォルトのものに戻すことができる。デフォルトのドキュメント・モードの判断ロジックについても、「Internet Explorer 9正式版レビュー」で解説しているため、そちらを参照してほしい。

○[Turn off Compatibility View list]サブメニュー

 IEは、互換性を維持するためにCompatibility View list(互換性ビュー・リスト)を提供している。IEは、HTMLコードを解析した結果で、描画エンジンを決定しているが、Webページは比較的ルーズに書かれていることが多く、単純なロジックで決定してしまっては、正しく表示されないケースが多くある。そのようなサイトを救うために、マイクロソフトは、互換性ビュー・リストを作成し、随時更新している。IE9では、自動的にこのリストを更新するようになっているが、最新のリストはここで公開されている。

 このサブメニューは、互換性ビュー・リストを無効にして、デフォルトの設定での描画を強制する機能だと思われるが、リストに含まれているいくつかのサイトを実際に開いてみても、問題といえるような影響が出ている箇所を見つけられなかった。

 問題点についてはいったん置いておいて、互換性ビュー・リストの変更方法について解説しよう。

 IE10では、以下のパスに互換性ビュー・リストが配置されている。

x86の場合:C:\Program Files\Internet Explorer Platform Preview\iecompatdata.xml
x64の場合:C:\Program Files(x86)\Internet Explorer Platform Preview\iecompatdata.xml
 ただし、IE10 PP1では、非常に限られたサイトしか互換性ビュー・リストに登録されていない。さらに追加でサイト情報が必要な場合は、互換性ビュー・リストをダウンロードして、上記の場所に自分で配置する必要がある。またそのとき、併せてレジストリの変更も必要になるため、注意が必要である。詳細な手順は、英語になってしまうが、リリース・ノートの「Platform Preview Compatibility List」に書かれているため、そちらを参照してほしい。

● 5-3. [Report Issue]メニュー

 [Report Issue]メニューには、問題点を報告するための機能が用意されている。Webページの閲覧やIE10 PP1の検証をしていて、明らかに不具合がある場合には、ここから報告できるようになっている。


[Report Issue]メニュー
○[Send Feedback]サブメニュー

 [Send Feedback]サブメニューをクリックすると、マイクロソフトにフィードバックを入力するためのダイアログが表示される。

 そのダイアログを使って、実際にフィードバックを送信するまでの手順を見ていこう。日本語でも報告ができるようなので、不具合が発生したときにはこのサブメニューを使ってほしい。


フィードバックを送信する手順1:[Issue details]ページ([Send an issue report]ダイアログ)
[Send Feedback]サブメニューをクリックすると、この[Send an issue report]ダイアログが表示される。
まずは、発生した問題の概要(タイトル)を記入する。
ビデオのアイコンをクリックすると、問題が発生する操作を実際に行って、その一連の操作を記録したビデオを添付して送ることができる。この例ではすでに記録済みのため、「IssueSteps.zip」というファイルが添付されていることが分かる。また、問題を発生させるための手順を入力する。
さらに詳細に問題の説明を記入する。
必要な場合、問題が発生したURLを記入する。
[Make my feedback visible to other Connect users](ほかのConnectユーザーと、この問題を共有する)チェックボックス。このフィードバックをマイクロソフトとのみ共有するか、ほかのMicrosoft Connectユーザーとも共有するかを選択する。企業内のシステムで外に公開できないものの場合、このチェックを外すとよい。
 ここまで記入したら、[Next]ボタンをクリックする。これにより、次の画面に切り替わる。


フィードバックを送信する手順2:[Identify your issue]ページ([Send an issue report]ダイアログ)
ここでは、問題のカテゴリを選択する。
問題の領域(=カテゴリ)を選択する。
を選択すると、さらに詳細な切り分けが出てくるため、適切なものを選択する。
 適切なカテゴリを選択できたら、[Next]ボタンをクリックして、ページを切り替える。


フィードバックを送信する手順3:[Additional information]ページ([Send an issue report]ダイアログ)
ここでは、追加情報を入力する。
IE9でもこの問題が発生するかを確認して、発生する場合は[Yes]を、発生しない場合は[No]を選択する。[I don't know]という選択肢も存在しているが、なるべく確認して[Yes]/[No]で選択するようにしてほしい。
どの程度の頻度で発生するかを選択する。
期待している振る舞いを記述する。
実際にはどうなったか(もしくは、期待する振る舞いとの違い)を記入する。
 記入が終わったら、[Next]をクリックして、ページを進める。


フィードバックを送信する手順4:[Confirm and Send]ページ([Send an issue report]ダイアログ)
ここでは、送信前の最終確認を行い、さらに添付情報があればそれも追加する。例えば、イベント・ログを含むさまざまなログ情報が添付されることになるが、ほかにも問題を解決するために必要になりそうな情報があれば、それもここで添付すればよい。
 最後に[Send Report]ボタンをクリックすれば、次の画面のページに切り替わり、実際に問題が(マイクロソフトへ)報告される。


フィードバックを送信する手順5:[Thank you!]ページ([Send an issue report]ダイアログ)
 この画面が出れば、送信完了である。[Microsoft Connect]リンクをクリックすれば、Microsoft Connectサイト上にあるIEのフォーラムを表示できる。ただし、Microsoft Connectは会員制のため、IEのフォーラムに参加する権限がない場合、開けない可能性もある。もし、開けなかったとしても、送信した問題はマイクロソフトと共有できているため、安心して解決を待ってほしい。

 ここまでの手順で送信した問題はMicrosoft Connectサイト上のフィードバック・センターで共有されている(※このリンク先は会員制サイトのため、すべての情報を閲覧できない可能性があるので注意してほしい)。

 前述の[Make my feedback visible to other Connect users](ほかのConnectユーザーと、この問題を共有する)チェックボックスにチェックを入れた場合、フォーラムの参加者は、その問題の内容を読めるため、解決策を提言したり、同じ問題が発生して困っている場合には「私もです」をクリックすることで、その問題で困っている人がほかにもいることを伝えたりできる。

 ここまでで、フィードバックの送信方法について解説してきたが、せっかく見付けた問題も、既知の問題やほかの人がすでに送信済みの問題を報告しても意味がない。リリース時点ですでに分かっている問題は、リリース・ノートの「Platform Preview Known Issues」に書かれているため、こちらを最初に確認するようにしてほしい。また、ほかの人と同じ報告を避けるために、アクセスできる権限がある場合は、フィードバック・センターですでに報告されていないかを一度検索してみてから送信することをお勧めする。

● 5-4. [ Help]メニュー

 [Help]メニューは、見てのとおり、あえて説明する必要はないかもしれないが、簡単に解説する。


[Help]メニュー
○[Using the Windows Internet Explorer Platform Preview]サブメニュー

 このサブメニューをクリックすると、ユーザー・ガイド(英語)が開くが、基本的な使い方や解説が完結に書かれているため、最初に読んでおくと理解を深められる。

○[About]サブメニュー

 このサブメニューをクリックすると、[About the Windows Internet Explorer Platform Preview]というバージョン番号ダイアログが表示される。


バージョン番号ダイアログ
この例では、バージョン番号が「10.0.1000.16394」であることを確認できる。
 このように、IE10 PP1のバージョンが「10.0.1000.16394」であることが確認できる。今後、このバージョン番号が上がっていくことになる。また、IE10 PP1のタイトルバーには、「2.10.1000.16394」と表示されているが、これは「ビルド番号」と呼ばれている。IE9のPlatform Previewのときには、「1.9.xxxx.xxxx」であった。

2011年6月4日土曜日

Google、IE7など旧バージョンブラウザのサポート終了

Googleは古いバージョンのWebブラウザーのサポートを段階的に終了することを発表した(公式ブログの記事)。 

8月1日からは、最新版および1つ前のバージョンのWebブラウザーのみがサポート対象となる。新しいバージョンのWebブラウザーが公開されるたびに、2つ前のバージョンのサポートを終了するとのことだ。 8月1日をもってサポート終了となるのはFirefox 3.5、Internet Explorer 7およびSafari 3。これらのブラウザを引き続き利用した場合にはGmailやGoogle Calendar、Google Talk、Google Docs及びGoogle Sitesの一部機能が使用できなくなる。最終的にはこれらのアプリケーションが全く動作しなくなるとのことだ。

2011年6月3日金曜日

Webの基本からクラウド、HTML5まで易しく解説するWeb絵本 Googleが公開

 Googleは6月2日、Webを利用する際に知っておきたい基本的な知識について解説する絵本の日本語版「ブラウザやウェブについて知っておきたい20のこと」を公開した。

 「IPアドレスとDNS」や「クラウドコンピューティング」「HTML5」やセキュリティなど、インターネットの基本から最新の動向まで20項目について解説している。

 Chromeブラウザを開発するチームがHTML5を活用して制作。オフラインでも利用でき、ページをめくったりする感覚をブラウザ上で実現している。ソースコードは公開しており、同様のWebブックを制作することが可能だ。

IE開発者ツールでJavaScriptコードを整形して表示するには?

 Webブラウジング中にショートカット・キー[F12]を押すと起動できる「開発者ツール」が、バージョン8以降のInternet Explorer(以下、IE)には搭載されている。開発者ツールは、現在
開いているWebページのHTMLコード内の各要素をツリー形式でビジュアルに表示したり、Webページ上の要素をクリックして、それに該当するコードを表示したり、HTMLコードやCSSプロパティなどをその場で試しに書き換えてリアルタイムにWebページの表示を変更したりできるなど、Web制作に役立つ機能がそろっている。そういったWeb開発用機能の1つとして、JavaScriptコードのデバッグ機能がある。

 IE9では、この開発者ツールが強化され、JavaScriptコードの書式を整形して、見やすく表示する機能が追加された。本TIPSでは、この機能の使い方を説明する。

■開発者ツール(IE9以降)のJavaScriptコード書式整形機能

 特に昨今のJavaScriptコードでは、通信量を極力減らして実行速度を高めるなどの目的で、コードの圧縮が行われている。そのため、生のJavaScriptコードは大変読みにくく、実際に稼働中のサイトのJavaScriptコードをデバッグしてみると、JavaScriptコードの解読に時間がかかってしまう場合がある。

 圧縮されているJavaScriptコードを解読したい場合には、IE9以降に実装されているJavaScriptコードの書式整形機能が役立つ。

 具体的には、開発者ツールの[スクリプト]タブのツールバー上にある[構成]ボタンをクリックして(ショートカット・キーは[Alt]+[Ctrl]+[O]キー)、表示されるメニューから[JavaScript の書式設定]をクリックする。

 これにより、JavaScriptコードの書式が整形され、読みやすくなる

 こうやって整形された状態でも、もちろんJavaScriptコードをデバッグできる。

2011年6月2日木曜日

Unique Authentication using Magic of HTML5 and WCF

This is my first hands on in HTML5. One day I thought about making an application which is simple and fancy looking as well. I had not worked earlier in HTML5, but once I saw the new features and tags in HTML5, I decided to make something new in core HTML. The biggest advantage in using HTML5 is that it is light weighted, platform independent and best for mobile applications like Iphone, Android (For Win 7 mobile, it's not supported because Microsoft is still experimenting with HTML5 and has not yet introduced HTML5 in mobile). Enough about my thoughts, let's moves on to the application. This application is based on Login form, but it is not a simple authentication form.
In this article, we'll build a innovative login form, where the user drops a "webid" file in the login form to authenticate. The file contains an image and some information about the card holder. It uses a great feature of HTML5, WCF and feature called WebId.
System Requirements
The most essential requirement to run this application is HTML5 supported browser.
Browser: Firefox 3.6.3, Google Chrome 5.0, Apple Safari 4.05, Opera 10.53
What You Can Learn
As a beginner, you can learn the following features:
a. HTML5, CSS3, WebKit
b. Ajax call to WCF service using JavaScript
c. JSON Operation in JavaScript.
Fancy Signup Form

I used this term (fancy) because I will tell you in simple terms how you can make a form look attractive.
As in figure of signup form, I divide the form in 3 sections:
1. User detail
2. Address detail
3. Image Upload
All sections are pretty simple except image upload section where I did not give any upload button. So how I can upload image? So I used the feature of drag and drop of HTML5 where you have to just drag and drop image in box. But here I applied a constraint along with it. You can't drag and drop image of more than 10 KB size. Since this is simple demo application, I was not going deep into it to resize image of any size, so I just put the constraint.
As you can see in the signup form rounded corner box, this is very simple CSS for webkit in HTML5:
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-khtml-border-radius: 5px;
border-radius: 5px;
You can give gradient effect using webkit at background in one line.
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#526ACE), to(#526ACE));
And you can browse more details in CSS from my code in the attachment.
Image Upload
Especially I wanted to give more details about this feature because it is more interesting for lazy people who don't want to navigate an image from desktop location and then upload it. I saved 5-6 seconds by using drag and drop feature of HTML5.
Let's have a look at how I can accomplish this task.
<fieldset>
<legend>Image Load</legend>
<ol>
<li><legend>Drag and Drop your Image here<legend>
<div id="holder">
</div>
<div id="status">
</div>

<script>
var y = null;
var holder = document.getElementById('holder'),
state = document.getElementById('status');

if (typeof window.FileReader === 'undefined') {
state.className = 'fail';
} else {
}
holder.ondragover = function()
{ this.className = 'hover'; return false; };
holder.ondragend = function()
{ this.className = ''; return false; };
holder.ondrop = function(e) {
this.className = '';
e.preventDefault();
var size = e.dataTransfer.files[0].size;
if (size > 10000) {
alert("Your image size is greater than
10 kb please Shrink image size");
window.location.reload(true);
}
else {
var file = e.dataTransfer.files[0],
reader = new FileReader();

reader.onload = function(event) {
holder.style.background =
'url(' + event.target.result + ') no-repeat center';
y = 'url(' + event.target.result + ') no-repeat center';
};
reader.readAsDataURL(file);
//var x = document.getElementById(el);
state.className = 'success';
state.innerHTML = 'Image SuccessFully Uploaded';
return false;
}
};
</script></li>
</ol>
</fieldset>
Although this code is self explanatory, I want to give some details on drag and drop feature. As you can see, I used div as a place in the form for drag and drop.
In the JavaScript, we are:
1. Searching for the drop target in the DOM using document.getElementByID.
2. When drag over event is fired (when the user drags the element over another), it will trigger the CSS class.
3. Bind the drop event, and within there, grab some data about what was dropped.
4. Now read the stream by reader and it will generate event.target.result that will help us to get an image in base 64 format which we further used as in webid.
For more details on new tags, please move to resources.
That is enough for fancy form decoration and JavaScript. Now we will move to Ajax calling WCF service.

Ajax Calls to WCF Service
Before describing snippet of Ajax call, I would like to give you a few details on WCF service at the server end. The service exposed as a REST URI in Post method. I want to send data as post because data would be too large. I used response format in JSON because it is easy to use in Ajax call. As this is a demo application, I did not use WCF in a professional way and just use as rooky.
Simple one method Signup User:
[OperationContract]
[WebInvoke(Method = "*",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "SignUpUser")]
string SignUpUser(string name, string email,string language, string phoneno,
string gender, string country, string image);
Implementation of the SignUpUser is very straight forward. I just make a webid format just as a JSON Format and send it to the appropriate mail. For making JSON string, I used inbuilt .NET serializer.
JavaScriptSerializer oSerializer = new JavaScriptSerializer();
string sJSON = oSerializer.Serialize(jsonWebIdList);
Web ID Format
We should create a file that we can drop on the form. It will be a text file with the extension "webid". The content is a JSON object containing all the data we need. One part of the file, named userdata, lists things as name, age, etc. Remember that you shouldn't trust the data in the file. It should only be used as feedback to the user on the login screen.
{
"filetype": "webid",
"signed":1234567890,

"userdata": {
"id": 1,
"name":"XYZ",
"gender": "Male",
"birthdate":19610804,
"phone":"1234567890",
"country":"us",
"language":"en_US",
"image": "" // Base 64 Image format
},
"keys": {
"Null"
}
}
Now I call signup service from JavaScript that will look like this:
var baseUrl = "http://localhost:54976/RestServiceImpl.svc/";

//Ajax request function for making ajax calling through other object
function AjaxRequest(baseurl, type, callbackResponse, parameterString) {
this.BaseURL = baseurl;
this.Type = type;
this.Callback = callbackResponse;
this.createXmlRequestObject();
this.ParemeterString = parameterString;
}

// Create XMLHTTP OBJECT
AjaxRequest.prototype.createXmlRequestObject = function() {
if (window.ActiveXObject) { // INTERNET EXPLORER
try {
this.xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
this.xmlHttp = false;
}
}
else { // OTHER BROWSERS
try {
this.xmlHttp = new XMLHttpRequest()
} catch (f) {
this.xmlHttp = false;
}
}

if (!this.xmlHttp) { // RETURN THE OBJECT OR DISPLAY ERROR
alert('there was an error creating the xmlhttp object');
} else {
//return this.xmlhttp;
}
}

AjaxRequest.prototype.MakeRequest = function() {
try {

// PROCEED ONLY IF OBJECT IS NOT BUSY
if (this.xmlHttp.readyState === 4 || this.xmlHttp.readyState === 0) {

// EXECUTE THE PAGE ON THE SERVER AND PASS QUERYSTRING
this.xmlHttp.open(this.Type, this.BaseURL, false);

var that = this;
// DEFINE METHOD TO HANDLE THE RESPONSE
this.xmlHttp.onreadystatechange = function() {
try {

// MOVE FORWARD IF TRANSACTION COMPLETE
alert(that.xmlHttp.readyState);
if (that.xmlHttp.readyState == 4) {
alert(that.xmlHttp.status);
// STATUS OF 200 INDICATES COMPLETED CORRECTLY
if (that.xmlHttp.status == 200) {

// WILL HOLD THE XML DOCUMENT
var xmldoc;
if (window.ActiveXObject) { // INTERNET EXPLORER
xmldoc = new ActiveXObject("Microsoft.XMLDOM");
xmldoc.async = "false";
that.Callback(that.xmlHttp.responseText);
}
else { // OTHER BROWSERS
//writeMessage("MakeRequest", that.xmlHttp.responseText);
that.Callback(that.xmlHttp.responseText);
}
}
}
}
catch (e)
{ alert(e) }
}

switch (this.Type) {
case "GET":
//this.xmlHttp.setRequestHeader("Content-type", "application/json");
// MAKE CALL
this.xmlHttp.send(this.BaseURL);
break;
case "POST":
this.xmlHttp.setRequestHeader("Content-type", "application/json");
this.xmlHttp.send(this.ParemeterString)
}

}
else {
// IF CONNECTION IS BUSY, WAIT AND RETRY
setTimeout('GetAllAppsService', 5000);
}
} catch (e) {
alert(e);
}
}
As you can see from the above code function, AjaxRequest creates XMLHttpRequest() object which further calls method AjaxRequest.prototype.MakeRequest. I used JavaScript in object oriented so that it can be used anywhere in calls easily. What you need to do is just make an object of AjaxRequest and call the function MakeRequest. For more details on how to use JavaScript as OOPS, please follow the trick from here.
You can also get some help form this article here.
Now call the Ajax request to WCF service just like:
AuthenticateLogin.prototype.SendDetailsToServer = function(parameters, localId) {

var url = baseUrl + "SignUpUser";
var parameterString = "{";

for (var i = 0; i < parameters.length; i++) {
parameterString = parameterString + '"'
+ parameters[i][0] + '":"'
+ parameters[i][1] + '" ,';
}

parameterString = parameterString.slice(0, parameterString.length - 1);
//writeMessage("AddNewReminderToServer", "Local id : "+localId);
parameterString = parameterString + "}";
var ajaxRequestObject = new AjaxRequest(url, "POST", function(responseText) {
var jsonobj = eval('(' + responseText + ')');
var result = jsonobj.SignUpUserResult;
if (result == "Successful") {
alert("SuccessfullyMail sent and you will redirect to login Page");
window.location = "http://localhost:54976/UI/latestLogin.htm";
}
else {
alert("Message sending Fail! Please try again");
window.location.reload(true);
}
// writeMessage("handleresponse", jsonstr);
// writeMessage(" -> local id :", ajaxRequestObject.TempItemID);
}, parameterString);

ajaxRequestObject.TempItemID = localId;
//writeMessage("AddNewReminderToServer", "Local id in ajax object : " +
//ajaxRequestObject.TempItemID);
ajaxRequestObject.MakeRequest();

}
One thing I would like to stay focused on is parameterString. I customized Body request in JSON Format because Ajax request header is in JSON format. So it will only accept JSON string in body.
this.xmlHttp.setRequestHeader("Content-type", "application/json");
this.xmlHttp.send(this.ParemeterString)
Here, function (responseText) is used as a callback function which will call once response is handed over by the Ajax request call. ResponseText is the result state when response sends back from the server in readystate 4 with status 200.
Now call:
function getDataFromthroughClass() {
var objSync = new AuthenticateLogin();
//string name, string email, string phoneNo, string gender, string country)
var name = document.getElementById("name").value;
var email = document.getElementById("email").value;
var phone = document.getElementById("phone").value;
var language = document.getElementById("language").value;
var gender = document.getElementById("gender").value;
var country = document.getElementById("country").value;
objSync.SendDetailsToServer(new Array(
new Array("name", name),
new Array("email", email),
new Array("language", language),
new Array("phoneno", phone),
new Array("gender", gender),
new Array("country", country),
new Array("image", y)));
}
Login Form
This section is pretty interesting and something different which I got from mattiasdanielsson. He gives a nice way to use web id as an authentication by using the drag and drop feature of HTML5.
What we used in login form when the user wants to authenticate, he drops a file (i.e. "xyz.webid") in the form, which is then read and parsed by JavaScript as JSON. Using jQuery, the users data (name, gender, etc.) is displayed in the drop zone, providing visual feedback to the user. If the file is parsed without error, an input is shown where the user enters his four-digit PIN number. The JavaScript then uses the PIN together with the "auth" string in the dropped file to create the key sent to the server... In this demo application, I don't use PIN authentication from server.
var objData;

$(document).ready(function() {

var $droptarget = $('#idBox'), $idCardSrc = $('#idCardSrc'),
$idBoxBg = $('#idBoxBg'),
$pinBox = $('#pinBox'), $pinInput = $('input', $pinBox);

$droptarget.bind('dragenter', function(e) {
e.stopPropagation();
e.preventDefault();
$droptarget.addClass('drophover');
$idBoxBg.text('Drop it now');
return false;
});
$droptarget.bind('dragleave', function(e) {
e.stopPropagation();
e.preventDefault();
$droptarget.removeClass('drophover');
$idBoxBg.text('Drop ID file here');
return false;
});
$droptarget.bind('dragover', function(e) {
e.stopPropagation();
e.preventDefault();
});
document.getElementById('idBox').addEventListener('drop', function(e) {
e.stopPropagation();
e.preventDefault();
For drag and drop of webid, we are required to add event handlers to all four events, and use both stopPropagation and preventDefault on them. Otherwise, your browser will just display the dropped file, and never fire the drop event. Also note that jQuery's bind() method is used with the first three handlers, but not the fourth. Since jQuery doesn't support the Event.dataTransfer object, we have to bind the drop event using native JavaScript.
Conclusion
I hope you will enjoy this different authentication login window by the magic of HTML5. As I stated from the outset, we can enhance this login authentication in a more logical way for very secure sites by the following method:
a. You can match base 64 image for validation.
b. Pin could be hashed in webid or just drop this pin in mail along with attachment of webid.
c. Encrypt webid (In this demo application, I did not used encryption.)
That's all about the application. For more details, please use the discussion panel.

Use HTML5 LocalStorage in your Mobile Web Applications

LocalStorage or DOM Storage provides Web pages with the ability to store named key/value pairs locally. This storage is different from the browser cookies. In some systems, it allows Web applications to store from 5MB to 10MB of application data. Unlike cookies, this data is not posted back to the server. It remains locally on the device, and it is persisted even after navigating to another site or closing the browser. Like cookies, this data can be removed if the user clears the browsing history.

This storage is ideal for Web mobile applications that do not require a lot of data storage, and all the data access can be done with scripting objects. When using the local storage, you should consider the following:

1. Validate that the local storage is available. This is available on browsers that support HTML5 and IE8+. Devices like IPhone, Android and BlackBerries support HTML5. Windows Mobile 7 may be getting HTML5 support in the middle of 2011.
2. For the keys, use a namespace that differentiates the Web applications in the same domain and append a unique token for that record.
3. Always check that the storage limit has not been reached. This exception would be raised when adding new items.

Simple data provider to illustrate the ability to add and read values from the Local Storage:

og.Data.Storage = {
isSupported: function () {
try {
return ('localStorage' in window && window['localStorage'] !== null);
} catch (e) {
return false;
}
},
Add: function (key, value) {
try {
localStorage.setItem(key, value);
//or localStorage[key] = value; //like associative arrays
} catch (e) {
alert(e.Description);
return -1;
}
},
Get: function (key) {
return localStorage.getItem(key);
//or localStorage[key];
}
}

This simple data provider implementation can be used to test if the localStorage is available. It also supports Add and Get methods. To use the provider, you could write a simple script as follows:

if (og.Data.Storage.isSupported()){
og.Data.Storage.Add("myapp.key1","value 1"); //notice the key name
og.Data.Storage.Add("myapp.key2","value 2");
var val1= og.Data.Storage.Get("myapp.key1");
var val2= og.Data.Storage.Get("myapp.key2");
}

If you need data storage for small Web apps, this may be something to look into.