I tried creating a simple silverlight application under some of MVVM pattern rules like followings.
・Views can do "CRUD" data only by "Data Binding" from ViewModels. ( CRUD : Create, Read, Update, Delete )
・Any events will be executed on ViewModels by "ICommand" from Views or some Behaviors on Views.
(which means there is no code behind on the view.)
⇒ "loose coupling" between a view and a viewmodel ( ViewとViewModelの疎結合 )
MVVM Pattern for Silverlight 4 Demo
http://demo.gehintleman.com/MVVMPattern.html
・There are 4 Views (including MainView), and all the Views do not have any code behinds.
・Views and ViewModels are managed through ExportAttribute/ImportAttribute.
・Using resource files(*.resx) for the localization.
MVVM Pattern could clearly devide web application development into coding by programmers and designing by designers.
* Differently from WPF, Silverlight cannot assign(bind) ViewModels to Views in Application.Resources in APP.XAML.
But, Managed Extensibility Framework ( a.k.a. MEF ) is so great that we can easily manage ViewModels and Views.
Wednesday, August 18, 2010
Sunday, July 18, 2010
Authentication in silverlight 4
Here is a preparation for Very Very Verrrrry simple Login System for Silverlight.
I. Server Side ( XXXXX.Web project )
1. Membership Provider class
namespace XXXXX.Web.Providers
{
public class CustomMembershipProvider : MembershipProvider
{
public override string ApplicationName { set; get; }
public override MembershipUser GetUser(string username, bool userIsOnline)
{
return new MembershipUser("CustomMembershipProvider",
username,
null,
null,
null,
null,
false,
false,
new DateTime(),
new DateTime(),
new DateTime(),
new DateTime(),
new DateTime());
}
public override bool ValidateUser(string username, string password)
{
if(username == "admin")
return password == "password";
if(username == "user")
return password == "password";
return false;
}
public override bool EnablePasswordReset { get { throw new NotImplementedException(); } }
public override bool EnablePasswordRetrieval { get { throw new NotImplementedException(); } }
public override bool RequiresQuestionAndAnswer { get { throw new NotImplementedException(); } }
public override int MaxInvalidPasswordAttempts { get { throw new NotImplementedException(); } }
public override int PasswordAttemptWindow { get { throw new NotImplementedException(); } }
public override bool RequiresUniqueEmail { get { throw new NotImplementedException(); } }
public override MembershipPasswordFormat PasswordFormat { get { throw new NotImplementedException(); } }
public override int MinRequiredPasswordLength { get { throw new NotImplementedException(); } }
public override int MinRequiredNonAlphanumericCharacters { get { throw new NotImplementedException(); } }
public override string PasswordStrengthRegularExpression { get { throw new NotImplementedException(); } }
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) { throw new NotImplementedException(); }
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) { throw new NotImplementedException(); }
public override string GetPassword(string username, string answer) { throw new NotImplementedException(); }
public override bool ChangePassword(string username, string oldPassword, string newPassword) { throw new NotImplementedException(); }
public override string ResetPassword(string username, string answer) { throw new NotImplementedException(); }
public override void UpdateUser(MembershipUser user) { throw new NotImplementedException(); }
public override bool UnlockUser(string userName) { throw new NotImplementedException(); }
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline) { throw new NotImplementedException(); }
public override string GetUserNameByEmail(string email) { throw new NotImplementedException(); }
public override bool DeleteUser(string username, bool deleteAllRelatedData) { throw new NotImplementedException(); }
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override int GetNumberOfUsersOnline() { throw new NotImplementedException(); }
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
}
}
2. Profile Provider class
namespace XXXXX.Web.Providers
{
public class CustomProfileProvider : ProfileProvider
{
public override string ApplicationName { set; get; }
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
{
var username = context["UserName"];
var result = new SettingsPropertyValueCollection();
result.Add(new SettingsPropertyValue(
new SettingsProperty(
"WelcomeMessage",
typeof(string),
null,
true,
string.Format("ようこそ {0}さん", username),
SettingsSerializeAs.String,
null,
false,
false)));
return result;
}
public override int DeleteProfiles(ProfileInfoCollection profiles) { throw new NotImplementedException(); }
public override int DeleteProfiles(string[] usernames) { throw new NotImplementedException(); }
public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) { throw new NotImplementedException(); }
public override int GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) { throw new NotImplementedException(); }
public override ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override ProfileInfoCollection GetAllInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override ProfileInfoCollection FindProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override ProfileInfoCollection FindInactiveProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection) { throw new NotImplementedException(); }
}
}
3. Role Provider class
namespace XXXXX.Web.Providers
{
public class CustomRoleProvider : RoleProvider
{
public override string ApplicationName { set; get; }
public override string[] GetRolesForUser(string username)
{
if (username == "admin")
return new[] { "Administrators", "Users" };
if (username == "user")
return new[] { "Users" };
return null;
}
public override bool IsUserInRole(string username, string roleName)
{
if(username == "admin")
return roleName == "Administrators" || roleName == "Users";
if(username == "user")
return roleName == "Users";
return false;
}
public override void CreateRole(string roleName) { throw new NotImplementedException(); }
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) { throw new NotImplementedException(); }
public override bool RoleExists(string roleName) { throw new NotImplementedException(); }
public override void AddUsersToRoles(string[] usernames, string[] roleNames) { throw new NotImplementedException(); }
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) { throw new NotImplementedException(); }
public override string[] GetUsersInRole(string roleName) { throw new NotImplementedException(); }
public override string[] GetAllRoles() { throw new NotImplementedException(); }
public override string[] FindUsersInRole(string roleName, string usernameToMatch) { throw new NotImplementedException(); }
}
}
4. User class
namespace XXXXX.Web.Providers
{
public class User : UserBase
{
public string WelcomeMessage { set; get; }
}
}
5. Authentication Domain Service class
[EnableClientAccess]
public class AuthenticationService : AuthenticationBase<User> { }
6. Web.Config
<system.web>
<authentication mode="Forms" />
<membership defaultProvider="customProvider">
<providers>
<clear />
<add name="customProvider" type="XXXXX.Web.Providers.CustomMembershipProvider"/>
</providers>
</membership>
<profile enabled="true" defaultProvider="customProvider">
<properties>
<add name="WelcomeMessage" allowAnonymous="false"/>
</properties>
<providers>
<clear />
<add name="customProvider" type="XXXXX.Web.Providers.CustomProfileProvider"/>
</providers>
</profile>
<roleManager enabled="true" defaultProvider="customProvider">
<providers>
<clear />
<add name="customProvider" type="XXXXX.Web.Providers.CustomRoleProvider"/>
</providers>
</roleManager>
</system.web>
II. Client side ( XXXXX project )
7. App.xaml.cs
public App()
{
this.Startup += this.Application_Startup;
this.Exit += this.Application_Exit;
this.UnhandledException += this.Application_UnhandledException;
InitializeComponent();
WebContext webcontext = new WebContext();
webcontext.Authentication = new FormsAuthentication();
this.ApplicationLifetimeObjects.Add(webcontext);
}
private void Application_Startup(object sender, StartupEventArgs e)
{
this.Resources.Add("WebContext", WebContext.Current);
//this.RootVisual = new MainPage();
this.RootVisual = new BasePage();
}
Here is the pages for the simple login system.
8. BasePage.xaml
<UserControl x:Class="XXXXX.BasePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
</UserControl>
9.BasePage.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace XXXXX
{
using XXXXX.Web;
public partial class BasePage : UserControl
{
public BasePage()
{
InitializeComponent();
if (this.Content == null)
{
this.Content = new LoginPage();
}
else
{
var user = WebContext.Current.User;
if (user.IsAuthenticated)
((BasePage)Parent).ShowMainPage();
else
((BasePage)Parent).ShowLoginPage();
}
}
public void ShowLoginPage()
{
this.Content = new LoginPage();
}
public void ShowMainPage()
{
this.Content = new MainPage();
}
}
}
** [IMPORTANT] **
10. MainPage.xaml.cs
add following code in the constructor.
var user = WebContext.Current.User;
if (!user.IsAuthenticated)
((BasePage)Parent).ShowLoginPage();
I know that using "business application template" is easier than the above way, but I hope it would be more customizable.
I. Server Side ( XXXXX.Web project )
1. Membership Provider class
namespace XXXXX.Web.Providers
{
public class CustomMembershipProvider : MembershipProvider
{
public override string ApplicationName { set; get; }
public override MembershipUser GetUser(string username, bool userIsOnline)
{
return new MembershipUser("CustomMembershipProvider",
username,
null,
null,
null,
null,
false,
false,
new DateTime(),
new DateTime(),
new DateTime(),
new DateTime(),
new DateTime());
}
public override bool ValidateUser(string username, string password)
{
if(username == "admin")
return password == "password";
if(username == "user")
return password == "password";
return false;
}
public override bool EnablePasswordReset { get { throw new NotImplementedException(); } }
public override bool EnablePasswordRetrieval { get { throw new NotImplementedException(); } }
public override bool RequiresQuestionAndAnswer { get { throw new NotImplementedException(); } }
public override int MaxInvalidPasswordAttempts { get { throw new NotImplementedException(); } }
public override int PasswordAttemptWindow { get { throw new NotImplementedException(); } }
public override bool RequiresUniqueEmail { get { throw new NotImplementedException(); } }
public override MembershipPasswordFormat PasswordFormat { get { throw new NotImplementedException(); } }
public override int MinRequiredPasswordLength { get { throw new NotImplementedException(); } }
public override int MinRequiredNonAlphanumericCharacters { get { throw new NotImplementedException(); } }
public override string PasswordStrengthRegularExpression { get { throw new NotImplementedException(); } }
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) { throw new NotImplementedException(); }
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) { throw new NotImplementedException(); }
public override string GetPassword(string username, string answer) { throw new NotImplementedException(); }
public override bool ChangePassword(string username, string oldPassword, string newPassword) { throw new NotImplementedException(); }
public override string ResetPassword(string username, string answer) { throw new NotImplementedException(); }
public override void UpdateUser(MembershipUser user) { throw new NotImplementedException(); }
public override bool UnlockUser(string userName) { throw new NotImplementedException(); }
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline) { throw new NotImplementedException(); }
public override string GetUserNameByEmail(string email) { throw new NotImplementedException(); }
public override bool DeleteUser(string username, bool deleteAllRelatedData) { throw new NotImplementedException(); }
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override int GetNumberOfUsersOnline() { throw new NotImplementedException(); }
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
}
}
2. Profile Provider class
namespace XXXXX.Web.Providers
{
public class CustomProfileProvider : ProfileProvider
{
public override string ApplicationName { set; get; }
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
{
var username = context["UserName"];
var result = new SettingsPropertyValueCollection();
result.Add(new SettingsPropertyValue(
new SettingsProperty(
"WelcomeMessage",
typeof(string),
null,
true,
string.Format("ようこそ {0}さん", username),
SettingsSerializeAs.String,
null,
false,
false)));
return result;
}
public override int DeleteProfiles(ProfileInfoCollection profiles) { throw new NotImplementedException(); }
public override int DeleteProfiles(string[] usernames) { throw new NotImplementedException(); }
public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) { throw new NotImplementedException(); }
public override int GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) { throw new NotImplementedException(); }
public override ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override ProfileInfoCollection GetAllInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override ProfileInfoCollection FindProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override ProfileInfoCollection FindInactiveProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection) { throw new NotImplementedException(); }
}
}
3. Role Provider class
namespace XXXXX.Web.Providers
{
public class CustomRoleProvider : RoleProvider
{
public override string ApplicationName { set; get; }
public override string[] GetRolesForUser(string username)
{
if (username == "admin")
return new[] { "Administrators", "Users" };
if (username == "user")
return new[] { "Users" };
return null;
}
public override bool IsUserInRole(string username, string roleName)
{
if(username == "admin")
return roleName == "Administrators" || roleName == "Users";
if(username == "user")
return roleName == "Users";
return false;
}
public override void CreateRole(string roleName) { throw new NotImplementedException(); }
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) { throw new NotImplementedException(); }
public override bool RoleExists(string roleName) { throw new NotImplementedException(); }
public override void AddUsersToRoles(string[] usernames, string[] roleNames) { throw new NotImplementedException(); }
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) { throw new NotImplementedException(); }
public override string[] GetUsersInRole(string roleName) { throw new NotImplementedException(); }
public override string[] GetAllRoles() { throw new NotImplementedException(); }
public override string[] FindUsersInRole(string roleName, string usernameToMatch) { throw new NotImplementedException(); }
}
}
4. User class
namespace XXXXX.Web.Providers
{
public class User : UserBase
{
public string WelcomeMessage { set; get; }
}
}
5. Authentication Domain Service class
[EnableClientAccess]
public class AuthenticationService : AuthenticationBase<User> { }
6. Web.Config
<system.web>
<authentication mode="Forms" />
<membership defaultProvider="customProvider">
<providers>
<clear />
<add name="customProvider" type="XXXXX.Web.Providers.CustomMembershipProvider"/>
</providers>
</membership>
<profile enabled="true" defaultProvider="customProvider">
<properties>
<add name="WelcomeMessage" allowAnonymous="false"/>
</properties>
<providers>
<clear />
<add name="customProvider" type="XXXXX.Web.Providers.CustomProfileProvider"/>
</providers>
</profile>
<roleManager enabled="true" defaultProvider="customProvider">
<providers>
<clear />
<add name="customProvider" type="XXXXX.Web.Providers.CustomRoleProvider"/>
</providers>
</roleManager>
</system.web>
II. Client side ( XXXXX project )
7. App.xaml.cs
public App()
{
this.Startup += this.Application_Startup;
this.Exit += this.Application_Exit;
this.UnhandledException += this.Application_UnhandledException;
InitializeComponent();
WebContext webcontext = new WebContext();
webcontext.Authentication = new FormsAuthentication();
this.ApplicationLifetimeObjects.Add(webcontext);
}
private void Application_Startup(object sender, StartupEventArgs e)
{
this.Resources.Add("WebContext", WebContext.Current);
//this.RootVisual = new MainPage();
this.RootVisual = new BasePage();
}
Here is the pages for the simple login system.
8. BasePage.xaml
<UserControl x:Class="XXXXX.BasePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
</UserControl>
9.BasePage.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace XXXXX
{
using XXXXX.Web;
public partial class BasePage : UserControl
{
public BasePage()
{
InitializeComponent();
if (this.Content == null)
{
this.Content = new LoginPage();
}
else
{
var user = WebContext.Current.User;
if (user.IsAuthenticated)
((BasePage)Parent).ShowMainPage();
else
((BasePage)Parent).ShowLoginPage();
}
}
public void ShowLoginPage()
{
this.Content = new LoginPage();
}
public void ShowMainPage()
{
this.Content = new MainPage();
}
}
}
** [IMPORTANT] **
10. MainPage.xaml.cs
add following code in the constructor.
var user = WebContext.Current.User;
if (!user.IsAuthenticated)
((BasePage)Parent).ShowLoginPage();
I know that using "business application template" is easier than the above way, but I hope it would be more customizable.
Change UserAgent on UIWebView ( Undocumented method )
I was looking for how to change the User Agent on UIWebView for iPhone/iPad.
then I found the solution... but it's undocumented method, which means it would be quite hard to get the approval from app store.
UIWebView+UserAgent.h
@interface UIWebView(UserAgent)
-(void)setUserAgent:(NSString *)userAgent;
@end
UIWebView+UserAgent.m
#import "UIWebView+UserAgent.h"
#import <objc/runtime.h>
@implementation UIWebView(UserAgent)
-(void)setUserAgent:(NSString *)userAgent
{
id webDocumentView;
id newWebView;
webDocumentView = objc_msgSend(self, @selector(_documentView));
object_getInstanceVariable(webDocumentView, "_webView", (void**)&newWebView);
objc_msgSend(newWebView, @selector(setCustomUserAgent:),userAgent);
}
@end
This would make the log analysis simpler by distinguishing precisely between Safari and the application on iPhone/iPad.
Plus, Providing some special services only for the application users on website is available by use of the UserAgent.
then I found the solution... but it's undocumented method, which means it would be quite hard to get the approval from app store.
UIWebView+UserAgent.h
@interface UIWebView(UserAgent)
-(void)setUserAgent:(NSString *)userAgent;
@end
UIWebView+UserAgent.m
#import "UIWebView+UserAgent.h"
#import <objc/runtime.h>
@implementation UIWebView(UserAgent)
-(void)setUserAgent:(NSString *)userAgent
{
id webDocumentView;
id newWebView;
webDocumentView = objc_msgSend(self, @selector(_documentView));
object_getInstanceVariable(webDocumentView, "_webView", (void**)&newWebView);
objc_msgSend(newWebView, @selector(setCustomUserAgent:),userAgent);
}
@end
This would make the log analysis simpler by distinguishing precisely between Safari and the application on iPhone/iPad.
Plus, Providing some special services only for the application users on website is available by use of the UserAgent.
Monday, March 29, 2010
localStorage vs sessionStorage in WebStorage
I checked out localStorage and sessionStorage.


Open another New Window

localStorage is useful for Offline Web Application or something.
| <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Web Storage Test</title> </head> <body onload="showAll()"> <h1>Web Storage Test</h1> <hr width="90%" align="left"> <h2>Local Storage</h2> Key:<input id="key1" type="text"> Value:<input id="value1" type="text"> <button onclick="save1()">Save</button> <br /> List:<select id="entries1" size="1" onchange="onEntrySelected1()"></select> <button onclick="remove1 ()">Remove</button> <button onclick="removeAll1()">Remove All</button> <br /> <hr width="90%" align="left"> <h2>Session Storage</h2> Key:<input id="key2" type="text"> Value:<input id="value2" type="text"> <button onclick="save2()">Save</button> <br /> List:<select id="entries2" onchange="onEntrySelected2()"></select> <button onclick="remove2()">Remove</button> <button onclick="removeAll2()">Remove All</button> <br /> <hr width="90%" align="left"> <button onclick="window.open(location.href);">window.open</button> <script type="text/javascript"> <!-- var key1 = document.getElementById("key1"); var value1 = document.getElementById("value1"); var key2 = document.getElementById("key2"); var value2 = document.getElementById("value2"); var entries1 = document.getElementById("entries1"); var entries2 = document.getElementById("entries2"); if (window.addEventListener) { window.addEventListener("storage", showAll, false); } else if (window.attachEvent) { //window.attachEvent("storage", showAll); document.write('<button onclick="window.location.reload();">Reload</button>'); } else { document.write('<button onclick="window.location.reload();">Reload</button>'); } function showAll() { entries1.innerHTML = ""; entries2.innerHTML = ""; for(var i=0; i<localStorage.length; i++) { var k = localStorage.key(i); entries1.options[entries1.options.length] = new Option(k+":"+localStorage[k], k); if(localStorage.length == 1) { key1.value = k; value1.value = localStorage[k]; } } for(var j=0; j<sessionStorage.length; j++) { var k = sessionStorage.key(j); entries2.options[entries2.options.length] = new Option(k+":"+sessionStorage[k], k); if(sessionStorage.length == 1) { key2.value = k; value2.value = sessionStorage[k]; } } } function save1() { localStorage[key1.value] = value1.value; } function remove1() { delete localStorage[key1.value]; } function removeAll1() { localStorage.clear(); } function onEntrySelected1() { var selectedOption = entries1.options[entries1.selectedIndex]; key1.value = selectedOption.value; value1.value = localStorage[selectedOption.value]; } function save2() { sessionStorage[key2.value] = value2.value; } function remove2() { delete sessionStorage[key2.value]; } function removeAll2() { sessionStorage.clear(); } function onEntrySelected2() { var selectedOption = entries2.options[entries2.selectedIndex]; key2.value = selectedOption.value; value2.value = sessionStorage[selectedOption.value]; } --> </script> </body> </html> |


Open another New Window

localStorage is useful for Offline Web Application or something.
Saturday, March 20, 2010
Trying the basic HTML5 part 2
I checked out Canvas element by the following code I made.
1. Firefox

2.Google Chrome

3. Opera

4. Internet Explorer Platform Preview ( IE9 Preview )

IE9 (Preview) does NOT support Canvas element YET.
(Though, I saw an article on the Internet, Microsoft wanted to separate the Canvas 2D API from HTML5.)
Anyway, the combination of HTML5 and Japascript would provide us to easily create a lot of Rich Internet Applications as if Flash.
By the way, separating between Javascript(external file) and HTML is better than the above code.
Plus, I re-coded Javascript to adjust the Clock size to the size of the canvas.
Clock.js
Clock.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <title>Analog clock by Javascript feat. HTML5</title> </head> <body> <canvas id="clock" width="300" height="300">現在お使いのブラウザはCanvas要素をサポートしていません。</canvas> <script type="text/javascript"> <!-- var canvas = document.getElementById('clock'); main(); function main() { if(canvas.getContext) { clock(); setInterval('clock()', 1000); } } function clock() { var context = canvas.getContext('2d'); context.save(); context.clearRect(0, 0, 300, 300); context.translate(150, 150); context.scale(1.5, 1.5); context.rotate( - Math.PI / 2 ); context.save(); // dial plate context.strokeStyle = "gray"; context.fillStyle = "white"; context.lineWidth = 4; context.lineCap = "round"; context.beginPath(); for (var i=0; i<12; i++) { context.rotate( Math.PI / 6 ); context.moveTo(60, 0); context.lineTo(70 + ( (i%3 == 2) ? 6 : 0 ), 0); } context.stroke(); context.restore(); context.save(); var now = new Date(); var hour = now.getHours(); var minute = now.getMinutes(); var second = now.getSeconds(); hour = (hour >= 12) ? (hour - 12) : hour; // hour hand context.strokeStyle = "black"; context.fillStyle = "black"; // calculating formula for the angle of the hour hand // ( 2 * Math.PI / 12 ) * hour + ( ( 2 * Math.PI / 12 ) / 60 ) * minute + ( ( ( 2 * Math.PI / 12 ) / 60 ) / 60 ) * second context.rotate( ( Math.PI / 6 ) * hour + ( Math.PI / 360 ) * minute + ( Math.PI / 21600 ) * second ); context.lineWidth = 8; context.lineCap = "round"; context.beginPath(); context.moveTo(-10, 0); context.lineTo(45, 0); context.stroke(); context.restore(); context.save(); // minute hand context.strokeStyle = "black"; context.fillStyle = "black"; // calculating formula for the angle of the minute hand // ( 2 * Math.PI / 60 ) * minute + ( ( 2 * Math.PI / 60 ) / 60 ) * second context.rotate( ( Math.PI / 30 ) * minute + ( Math.PI / 1800 ) * second ); context.lineWidth = 6; context.lineCap = "round"; context.beginPath(); context.moveTo(-14, 0); context.lineTo(62, 0); context.stroke(); context.restore(); context.save(); // second hand context.strokeStyle = "red"; context.fillStyle = "red"; // calculating formula for the angle of the second hand // ( 2 * Math.PI / 60 ) * second context.rotate( Math.PI / 30 * second ); context.lineWidth = 4; context.lineCap = "round"; context.beginPath(); context.moveTo(-15, 0); context.lineTo(70, 0); context.stroke(); context.restore(); // frame context.beginPath(); context.lineWidth = 12; context.strokeStyle = "green"; context.arc(0, 0, 90, 0, Math.PI * 2, true); context.stroke(); context.restore(); } //--> </script> </body> </html> |
1. Firefox

2.Google Chrome

3. Opera

4. Internet Explorer Platform Preview ( IE9 Preview )

IE9 (Preview) does NOT support Canvas element YET.
(Though, I saw an article on the Internet, Microsoft wanted to separate the Canvas 2D API from HTML5.)
Anyway, the combination of HTML5 and Japascript would provide us to easily create a lot of Rich Internet Applications as if Flash.
By the way, separating between Javascript(external file) and HTML is better than the above code.
Plus, I re-coded Javascript to adjust the Clock size to the size of the canvas.
Clock.js
| function Clock(id) { this.id = id; this.canvas = document.getElementById(id); if(this.canvas.getContext) { this.context = this.canvas.getContext('2d'); this.centerX = this.canvas.width / 2; this.centerY = this.canvas.height / 2; this.clocksize = 0; this.hour = 0; this.minute = 0; this.second = 0; this.CanStartClock = true; } } Clock.prototype = { Draw:function () { if(this.canvas.getContext) { this.Init(); this.DrawDialplate(); this.DrawHourHand(); this.DrawMinuteHand(); this.DrawSecondHand(); this.DrawFrame(); } }, Init:function() { var now = new Date(); var hour24 = now.getHours(); this.hour = (hour24 >= 12) ? (hour24 - 12) : hour24; this.minute = now.getMinutes(); this.second = now.getSeconds(); this.clocksize = this.canvas.width > this.canvas.height ? this.canvas.height : this.canvas.width; this.canvas.width = this.canvas.width; this.canvas.height = this.canvas.height; this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); this.context.translate(this.centerX, this.centerY); this.context.scale(1.5, 1.5); this.context.rotate( - Math.PI / 2 ); this.context.save(); }, DrawDialplate:function() { this.context.strokeStyle = "gray"; this.context.fillStyle = "white"; this.context.lineWidth = this.clocksize * 0.005; this.context.lineCap = "round"; this.context.beginPath(); for (var i=0; i<12; i++) { this.context.rotate( Math.PI / 6 ); this.context.moveTo(this.clocksize * 0.22, 0); this.context.lineTo((this.clocksize * 0.25),0); } this.context.stroke(); this.context.restore(); this.context.save(); }, DrawHourHand:function() { this.context.strokeStyle = "black"; this.context.fillStyle = "black"; this.context.rotate( ( Math.PI / 6 ) * this.hour + ( Math.PI / 360 ) * this.minute + ( Math.PI / 21600 ) * this.second ); this.context.lineWidth = this.clocksize * 0.025 ; this.context.lineCap = "round"; this.context.beginPath(); this.context.moveTo( - this.clocksize / 60, 0); this.context.lineTo(this.clocksize / 6.5, 0); this.context.stroke(); this.context.restore(); this.context.save(); }, DrawMinuteHand:function() { this.context.strokeStyle = "black"; this.context.fillStyle = "black"; this.context.rotate( ( Math.PI / 30 ) * this.minute + ( Math.PI / 1800 ) * this.second ); this.context.lineWidth = this.clocksize * 0.015; this.context.lineCap = "round"; this.context.beginPath(); this.context.moveTo( - this.clocksize / 60, 0); this.context.lineTo(this.clocksize / 4.8, 0); this.context.stroke(); this.context.restore(); this.context.save(); }, DrawSecondHand:function() { this.context.strokeStyle = "red"; this.context.fillStyle = "red"; this.context.rotate( Math.PI / 30 * this.second ); this.context.lineWidth = this.clocksize * 0.01; this.context.lineCap = "round"; this.context.beginPath(); this.context.moveTo( - this.clocksize / 40, 0); this.context.lineTo(this.clocksize / 4.2, 0); this.context.stroke(); this.context.restore(); this.context.save(); }, DrawFrame:function() { this.context.beginPath(); this.context.lineWidth = this.clocksize / 40; this.context.strokeStyle = "green"; this.context.arc(0, 0, (this.clocksize / 3.5), 0, Math.PI * 2, true); this.context.stroke(); this.context.restore(); this.context.save(); } } |
Clock.html
| <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <title>Analog clock by Javascript feat. HTML5</title> <script type="text/javascript" src="Clock.js"></script> </head> <body> <canvas id="clock" width="300" height="300">現在お使いのブラウザはCanvas要素をサポートしていません。</canvas> <script type="text/javascript"> <!-- clock = new Clock('clock'); Main = function() { clock.Draw(); setTimeout(this.Main, 100); } Main(); --> </script> </body> </html> |
Friday, March 19, 2010
Trying the basic HTML5
Today, I was checking out the basic code of HTML5 like following.
1. Internet Explorer 8

Of course it doesn't work, because IE8 does not support HTML5.
(Internet Explorer 8 version 8.0.6001.18882)
2. Internet Explorer Platform Preview (IE9 Preview)


*Select [Page]-[Open] in the menu.


* Enter URL in the Open-box. ("http://ie.microsoft.com/testdrive/" is set as default)
Windows Internet Explorer Platform Preview, version 1.9.7745.6019
(Internet Explorer version 9.0.7745.6019)
3.Firefox(version 3.6)


* Enter about:config in the location bar




*Enter "html5" in the filter-box to find "html5.enable"


*Do Double-Click in the html5.enable to change the value from false to true.
(Firefox version 3.6)
4.Google Chrome and Opera


(Google Chrome version 4.1.249.1036)
(Opera version 10.50 build 3296)
I think those must depend on their layout engines or something...
Well, I have to think/feel the next-generation Internet contents are definitely coming along with such an architecture.
| <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <title>HTML5 Demo</title> </head> <body> <svg><circle r="50" cx="50" cy="50" fill="red" Stroke="blue" Stroke-width="2" /></svg> </body> </html> |
1. Internet Explorer 8

Of course it doesn't work, because IE8 does not support HTML5.
(Internet Explorer 8 version 8.0.6001.18882)
2. Internet Explorer Platform Preview (IE9 Preview)


*Select [Page]-[Open] in the menu.


* Enter URL in the Open-box. ("http://ie.microsoft.com/testdrive/" is set as default)
Windows Internet Explorer Platform Preview, version 1.9.7745.6019
(Internet Explorer version 9.0.7745.6019)
3.Firefox(version 3.6)


* Enter about:config in the location bar




*Enter "html5" in the filter-box to find "html5.enable"


*Do Double-Click in the html5.enable to change the value from false to true.
(Firefox version 3.6)
4.Google Chrome and Opera


(Google Chrome version 4.1.249.1036)
(Opera version 10.50 build 3296)
I think those must depend on their layout engines or something...
Well, I have to think/feel the next-generation Internet contents are definitely coming along with such an architecture.
Thursday, March 18, 2010
Internet Explorer Platform Preview
I checked out how IE9 is going to work by ie9 preview.
Next generation browsers must be greater than current ones because of HTML5,hardware accelerated and JavaScript as well.
Internet Explorer Platform Preview TestDrive
http://ie.microsoft.com/testdrive/Default.html




トップのこの画像。。。Dragon Ball のカリン塔?
Next generation browsers must be greater than current ones because of HTML5,hardware accelerated and JavaScript as well.
Internet Explorer Platform Preview TestDrive
http://ie.microsoft.com/testdrive/Default.html




トップのこの画像。。。Dragon Ball のカリン塔?
Subscribe to:
Posts (Atom)