Archive

Author Archive

Open link in external browser using Phonegap Webworks for Blackberry

If you are developing apps for BlackBerry using PhoneGap / Webworks for Blackberry, then you have probably noticed that  if you add a url to an external website, such as <a href=”http://www.google.com”>Google</a&gt;, then the destination website gets loaded within the frame of the app, giving a poor user experience, and no way to return to the app, apart from closing the app.

The solution is not obvious, since you have to use Webworks API (which is not cross-platform, it’s BlackBerry only).

use the following code when itializing JQuery

$(‘a[target=”_blank”]’).live( ‘click’, function()
{
if ( window.blackberry )
{
alert( ‘Loading website: ‘ + $(this).attr( ‘href’ ) );
var args = new blackberry.invoke.BrowserArguments( $(this).attr( ‘href’ ));
blackberry.invoke.invoke(blackberry.invoke.APP_BROWSER, args);
return false;
}
return true;
})

Then IMPORTANTLY add the following lines to the config.xml

<feature id=”blackberry.app” required=”true” version=”1.0.0.0″/>

<feature id=”blackberry.invoke”/>
<feature id=”blackberry.invoke.BrowserArguments” />

<access uri =”*”/>

I have heard that this invocation mechanism may change for BlackBerry 10 / Playbook, which I am going to test soon.

Categories: Uncategorized

Sort DOM Elements using JQuery

If you want to save a round-trip to the server when changing the sort-order of a list of HTML Elements, you can use Javascript and JQuery quite simply with this handy bit of code:

 

<html>
<head>
<script src=”jquery-1.8.2.js”></script>
<script language=”javascript”>
$(init);
function init()
{
var listitems = $(“#sortContainer .sortable”).get();
listitems.sort(function(a, b) {
return $(a).attr(“value”) – $(b).attr(“value”);
});
$.each(listitems, function(index, item) { $(“#sortContainer”).append(item); });
}
</script>
</head>
<body>
<div id=”sortContainer”>
<div class=”sortable” value=”5″>5<br></div>
<div class=”sortable” value=”2″>2<br></div>
<div class=”sortable” value=”1″>1<br></div>
<div class=”sortable” value=”10″>10<br></div>
</div>
</body>
</html>

 

Categories: Uncategorized

Using HTML markup to display dynamic information

I wanted to associate Longitude & Latitude values with HTML elements on a page, and then using this data, display the KM distance from the current location. Using JQuery, and omitting the HTML5 Geolocation code, this is what I came up with

<html>
<head>
<script src=”jquery-1.8.2.js”></script>
<script lanaguage=”javascript”>
$(init);
function init()
{
$(“.autoDistance”).each(function()
{
$(this).html(renderDistance($(this)));
}
);
}
function renderDistance(obj,position)
{
var a = {
Latitude:obj.attr(“latitude”),
Longitude:obj.attr(“longitude”)
};
var b = { latitude:55.1, longitude:-6.9}; // current location
var distance = Math.sqrt(Math.pow( 69.1 * (a.Latitude – b.latitude),2) +
Math.pow(53.0 * (a.Longitude – b.longitude),2)) * 1.609344;
return Math.round(distance) + ” KM”;
}
</script>
</head>
<body>
Waypoint 1: <div class=”autoDistance” latitude=”55″ longitude=”-7″></div>
<br>
Waypoint 2: <div class=”autoDistance” latitude=”10″ longitude=”-7″></div>
</body>
</html>

Hope this helps someone!

Categories: Uncategorized

BlackBerry 10 Submissions open to developers

Categories: Uncategorized

Decode Google Recaptcha with C#

The Google Recaptcha system is one of the most popular Captcha systems in use. To beat it, you’ll need to subscribe to a Human Captcha API, What I used was FastTypers.org (Also known as HumanCoders or ExpertDecoders). To test this, I used the standard Recaptcha setup under ASP.NET CLR4 using the code downloaded from http://code.google.com/p/recaptcha/source/browse/trunk/recaptcha-plugins/

I set up a Windows forms application, with a button called btnReCaptcha, and ran the Recaptcha website under the virtual folder /Recaptcha.Test-CLR4/  – and here is the code – Note the code 6Lf9udYSAAAAAGF0LkIu3QsmMPfanZH3T8EXs9fA is the public key that will be contained in the HTML code of the website hosting the website.

private void btnReCaptcha_Click(object sender, EventArgs e)
{
var wc = new WebClient();
var strHtml = wc.DownloadString(“http://www.google.com/recaptcha/api/challenge?k=6Lf9udYSAAAAAGF0LkIu3QsmMPfanZH3T8EXs9fA&hl=&&#8221;);
const string strChallengeRegex = @”challenge.{4}(?<Challenge>[\w-_]+)”;
var strChallenge = Regex.Match(strHtml, strChallengeRegex).Groups[“Challenge”].Value;
var bImage = wc.DownloadData(“http://www.google.com/recaptcha/api/image?c=&#8221; + strChallenge);
var solver = new CaptchaSolver();
solver.SolveCaptcha(bImage);
var strImageText = solver.LastResponseText;
strHtml = wc.DownloadString(“http://localhost/Recaptcha.Test-CLR4/&#8221;);
var strViewstate = GetViewStateFromHtml(strHtml, true);
var strEventValidation = GetEventValidationFromHtml(strHtml);
var strPostData = “__EVENTTARGET=”;
strPostData += “&__EVENTARGUMENT=”;
strPostData += “&__VIEWSTATE=” + strViewstate;
strPostData += “&__EVENTVALIDATION=” + strEventValidation;
strPostData += “&recaptcha_challenge_field=” + strChallenge;
strPostData += “&recaptcha_response_field=” + strImageText;
strPostData += “&RecaptchaButton=Submit”;
wc.Headers[HttpRequestHeader.ContentType] = “application/x-www-form-urlencoded”;
string HtmlResult = wc.UploadString(“http://localhost/Recaptcha.Test-CLR4/&#8221;, strPostData);
}

/// <summary>
/// Gets a ASP.NET Viewstate from an aspx page.
/// </summary>
/// <param name=”strHtml”>The HTML to extract the viewstate string from.</param>
/// <param name=”urlEncode”>Should the response be Url Encoded.</param>
/// <returns></returns>
public static string GetViewStateFromHtml(string strHtml, bool urlEncode)
{
const string strViewStateRegex = @”__VIEWSTATE.*value..(?<viewstate>[/\w\+=]+)”;
var strViewState = Regex.Match(strHtml, strViewStateRegex, RegexOptions.Compiled).Groups[“viewstate”].Value;
if (urlEncode) { strViewState = HttpUtility.UrlEncode(strViewState); }
return strViewState;
}

/// <summary>
/// Gets a ASP.NET EventValidation from an aspx page, it will be already urlencoded.
/// </summary>
/// <param name=”strHtml”></param>
/// <returns></returns>
public static string GetEventValidationFromHtml(string strHtml)
{
var strEventValidationRegex = @”__EVENTVALIDATION.{32}(?<EventValidation>[/\w\+=]+)”;
var strEventValidation = Regex.Match(strHtml, strEventValidationRegex, RegexOptions.Compiled).Groups[“EventValidation”].Value;
if (strEventValidation.Length % 4 != 0)
{
// Invalid Capture, try another regex.
strEventValidationRegex = @”__EVENTVALIDATION..value..(?<EventValidation>[/\w\+=]+)”;
strEventValidation = Regex.Match(strHtml, strEventValidationRegex, RegexOptions.Compiled).Groups[“EventValidation”].Value;
}
strEventValidation = HttpUtility.UrlEncode(strEventValidation);
return strEventValidation;
}

Basically, it makes a request to Google for a Challenge key, uses the challenge key to get the image, passes the image to the Human OCR API, and then  captures the Viewstate and Event Validation from the page, then posts the decoded text, challenge key, back to the webserver.

Categories: Uncategorized

Use jQuery to include a include a Twitter feed

This snippet is designed for mobile apps, but with a suitable proxy, it would work on websites too.

<html>
<head>
<script src=”jquery.js”></script>
<script language=”javascript”>
$(init);
function init()
{
$.get(‘http://api.twitter.com/1/statuses/user_timeline.json?screen_name=petruccimusic&#8217;, function(data) {
var strHtml = “<ul>”;
for(var i in data)
{
var strText2 = replaceURLWithHTMLLinks(data[i].text);
strHtml += “<li>” + strText2 + “</li>”;
}
strHtml += “</ul>”;
$(“.result”).html(strHtml);
});
}
function replaceURLWithHTMLLinks(text) {
var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/i;
return text.replace(exp,”<a href=’$1′>$1</a>”);
}
</script>
</head>
<body>
<div class=”result”></div>
</body>
</html>

 

Categories: Uncategorized

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.

 

Categories: Uncategorized

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&gt;
<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”

Categories: Uncategorized

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;

Categories: Uncategorized

‘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.

Categories: Uncategorized