<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>mFabrik - mobile sites, apps, HTML5 and CMS software development &#187; javascript</title>
	<atom:link href="http://blog.mfabrik.com/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mfabrik.com</link>
	<description>Freedom delivered.</description>
	<lastBuildDate>Wed, 03 Aug 2011 09:47:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>AJAX proxy view with Python, urllib and Plone</title>
		<link>http://blog.mfabrik.com/2011/08/02/ajax-proxy-view-with-python-urllib-and-plone/</link>
		<comments>http://blog.mfabrik.com/2011/08/02/ajax-proxy-view-with-python-urllib-and-plone/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 08:26:42 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[plone]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[access control]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[allow-access-origin]]></category>
		<category><![CDATA[cors]]></category>
		<category><![CDATA[cross domain]]></category>
		<category><![CDATA[getjson]]></category>
		<category><![CDATA[grok]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[restful]]></category>

		<guid isPermaLink="false">http://blog.mfabrik.com/?p=1365</guid>
		<description><![CDATA[Old web browsers do not support Allow-acces-origin HTTP header needed to do cross-domain AJAX requests (IE6, IE7). Below is an example how to work around this for jQuery getJSON() calls by Detecting browsers which do not support this using jQuery.support API Doing an alternative code path through a local website proxy view which uses Python [...]]]></description>
			<content:encoded><![CDATA[<div class="body">
<p>Old web browsers do not support <a class="reference external" href="https://developer.mozilla.org/en/HTTP_access_control">Allow-acces-origin HTTP header</a> needed to do cross-domain AJAX requests (IE6, IE7).</p>
<p>Below is an example how to work around this for jQuery getJSON() calls by</p>
<ul class="simple">
<li>Detecting browsers which do not support this using jQuery.support API</li>
<li>Doing an alternative code path through a local website proxy view which uses Python <tt class="docutils literal">urllib</tt> to make server-to-server call and return it as it would be a local call, thus working around cross-domain restriction</li>
</ul>
<p>This example is for Plone/Grok, but the code is easily port to other Python web frameworks.</p>
<div class="note">
<p class="last"><em>Note: This is not a full example code. Basic Python and Javascript skills are needed to interpret and adapt the code for your use case.</em></p>
</div>
<p>Javascript example</p>
<pre class="literal-block">/**
 * Call a RESTful service vie AJAX
 *
 * The final URL is constructed by REST function name, based
 * on a base URL from the global settings.
 *
 * If the browser does not support cross domain AJAX calls
 * we'll use a proxy function on the local server. For
 * performance reasons we do this only when absolutely needed.
 *
 * @param {String} functionName REST function name to a call
 *
 * @param {Object} Arguments as a dictionary like object, passed to remote call
 */
function callRESTful(functionName, args, callback) {

    var src = myoptions.restService + "/" +functionName;

    // set to true to do proxied request on every browser
    // useful if you want to use Firebug to debug your server-side proxy view
    var debug = false;

        console.log("Doing remote call to:" + src)

        // We use jQuery API to detect whether a browser supports cross domain AJAX calls
        // http://api.jquery.com/jQuery.support/
        if(!jQuery.support.cors || debug) {
                // http://alexn.org/blog/2011/03/24/cross-domain-requests.html
                // Opera 10 doesn't have this feature, neither do IExplorer &lt; 8, Firefox &lt; 3.5

                console.log("Mangling getJSON to go through a local proxy")

                // Change getJSON to go to our proxy view on a local server
                // and pass the orignal URL as a parameter
                // The proxy view location is given as a global JS variable
                args.url = src;
                src = myoptions.portalUrl + "/@@proxy";
        }

        // Load data from the server
        $.getJSON(src, args, function(data) {
                // Parse incoming data and construct Table rows according to it
                console.log("Data succesfully loaded");
                callback(data, args);

     });

}</pre>
<p>The server-side view:</p>
<pre class="literal-block">import socket
import urllib
import urllib2
from urllib2 import HTTPError

from five import grok
from Products.CMFCore.interfaces import ISiteRoot
from mysite.app import options

class Proxy(grok.CodeView):
    """
    Pass a AJAX call to a remote server. This view is mainly indended to be used
    with jQuery.getJSON() requests.

    This will work around problems when a browser does not support Allow-Access-Origin HTTP header (IE).

    Asssuming only HTTP GET requests are made.s
    """

    # This view is available only at the root of Plone site
    grok.context(ISiteRoot)

    def isAllowed(self, url):
        """
        Check whether we are allowed to call the target URL.

        This prevents using your service as an malicious proxy
        (to call any internet service).
        """

        allowed_prefix = options.REST_SERVICE_URL

        if url.startswith(allowed_prefix):
            return True

        return False

    def render(self):
        """
        Use HTTP GET ``url`` query parameter for the target of the real request.
        """

        # Make sure any theming layer won't think this is HTML
        # http://stackoverflow.com/questions/477816/the-right-json-content-type
        self.request.response.setHeader("Content-type", "application/json")

        url = self.request.get("url", None)
        if not url:
            self.request.response.setStatus(500, "url parameter missing")

        if not self.isAllowed(url):
            # The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeate
            self.request.response.setStatus(403, "proxying to the target URL not allowed")
            return

        # Pass other HTTP GET query parameters direclty to the target server
        params = {}
        for key, value in self.request.form.items():
            if key != "url":
                params[key] = value

        # http://www.voidspace.org.uk/python/articles/urllib2.shtml
        data = urllib.urlencode(params)

        full_url = url + "?" + data
        req = urllib2.Request(full_url)

        try:

            # Important or if the remote server is slow
            # all our web server threads get stuck here
            # But this is UGLY as Python does not provide per-thread
            # or per-socket timeouts thru urllib
            orignal_timeout = socket.getdefaulttimeout()
            try:
                socket.setdefaulttimeout(10)

                response = urllib2.urlopen(req)
            finally:
                # restore orignal timeoout
                socket.setdefaulttimeout(orignal_timeout)

            # XXX: How to stream respone through Zope
            # AFAIK - we cannot do it currently

            return response.read()

        except HTTPError, e:
            # Have something more useful to log output as plain urllib exception
            # using Python logging interface
            # http://docs.python.org/library/logging.html
            logger.error("Server did not return HTTP 200 when calling remote proxy URL:" + url)
            for key, value in params.items():
                logger.error(key + ": "  + value)

            # Print the server-side stack trace / error page
            logger.error(e.read())

            raise e</pre>
</div>
<p class="signature">
<a href="http://mfabrik.com/@@zoho-contact-form"><img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/mfabrik-24.png"></a> <a href="http://mfabrik.com/@@zoho-contact-form">Get developers</a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml"><img valign="middle" src="http://www.feedburner.com/fb/images/pub/feed-icon16x16.png" alt="" style="vertical-align:middle;border:0"/></a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml">Subscribe mFabrik blog in a reader</a> <a href="http://twitter.com/mfabrik"> <img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/twitter-24.png"></a> <a href="http://twitter.com/moo9000">Follow me on Twitter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2011/08/02/ajax-proxy-view-with-python-urllib-and-plone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Everyone loves and hates console.log()</title>
		<link>http://blog.mfabrik.com/2011/03/15/everyone-loves-and-hates-console-log/</link>
		<comments>http://blog.mfabrik.com/2011/03/15/everyone-loves-and-hates-console-log/#comments</comments>
		<pubDate>Tue, 15 Mar 2011 13:35:40 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[commit hook]]></category>
		<category><![CDATA[compress]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[ie]]></category>
		<category><![CDATA[internet explorer]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[plone]]></category>
		<category><![CDATA[preprocessor]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[safari]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://blog.mfabrik.com/?p=1119</guid>
		<description><![CDATA[console.log()  is the best friend of every Javascript junkie. However, the lack of it isn&#8217;t. console.log() function is only available in Webkit based browsers and with Firebug in Firefox. It&#8217;s the infamous situation that someone leaves console.log() to Javascript code, doesn&#8217;t notice its presence, commits the file and suddenly all Javascript on the production server [...]]]></description>
			<content:encoded><![CDATA[<p>console.log()  is the best friend of every Javascript junkie. However, the lack of it isn&#8217;t. console.log() function is only available in Webkit based browsers and with Firebug in Firefox. It&#8217;s the infamous situation that someone leaves console.log() to Javascript code, doesn&#8217;t notice its presence, commits the file and suddenly all Javascript on the production server stops working for Internet Explorer users&#8230;.</p>
<p>To tackle the lack of console.log() problem there are several approaches.</p>
<h2>Use dummy placeholder if console is missing</h2>
<p>This snippet wraps console.log (need to repeat for console.error etc.):</p>
<pre>// Ignore console on platforms where it is not available
if (typeof(window["console"]) == "undefined") { console = {}; console.log = function(a) {}; }</pre>
<p>Pros</p>
<ul>
<li>Easy</li>
</ul>
<p>Cons</p>
<ul>
<li>Need to add to every Javascript file</li>
<li>Messes with global namespace</li>
</ul>
<h2>Use module specific log function</h2>
<p>This makes your code little bit ugly, more Java like. Each Javascript module declares their own log() function which checks the existence of console.log() and outputs there if it&#8217;s present.</p>
<pre>mfabrik.log =function(x) {
 if(console.log) {
 console.log(x);
 }
}

mfabrik.log("My log messages")</pre>
<p>Pros</p>
<ul>
<li>Easy to hook other logg</li>
<li>You can disable all logging output with one if</li>
</ul>
<p>Cons</p>
<ul>
<li>Not as natural to write as console.log()</li>
<li>Need to add to every Javascript module</li>
</ul>
<h2>Preprocess Javascript files</h2>
<p>Plone (Kukit / KSS) uses this approach. All debug Javascript is  hidden behind conditional comments and it is filtered out when JS files  are bundled for the production deployment. (<a href="http://codespeak.net/svn/kukit/kss.core/trunk/kss/core/pluginregistry/_concatresource/compression/javascript.py">The preprocessing code is here in Python for those who are interested in it</a>).</p>
<pre>if (_USE_BASE2) {
 // Base2 legacy version: matchAll has to be used
 // Base2 recent version: querySelectorAll has to be used
 var _USE_BASE2_LEGACY = (typeof(base2.DOM.Document.querySelectorAll) == 'undefined');
 if (! _USE_BASE2_LEGACY) {
 ;;;     kukit.log('Using cssQuery from base2.');</pre>
<p>Pros</p>
<ul>
<li>Makes production Javascript files lighter</li>
<li>Make production Javascript files more professional &#8211; you do not deliver logging statements indented for internal purposes for your site visitors</li>
</ul>
<p>Cons</p>
<ul>
<li>Complex &#8211; preprocessing is required</li>
</ul>
<h2>Commit hooks</h2>
<p>You can use Subversion and Git commit hooks to check that committed JS files do not contain console.log. For example, Plone repositories do this for the Python statement  import pdb ; pdb.set_trace() (enforce pdb breakpoint).</p>
<p>Pros</p>
<ul>
<li>Very robust approach &#8211; you cannot create code with console.log()</li>
</ul>
<p>Cons</p>
<ul>
<li>Prevents also legitimate use of console.log()</li>
<li>Github, for example, lacks possibility to push client-side commit hooks to the repository cloners. This means that every developer must manually install commit hooks themselves. Everything manual you need to do makes the process error prone.</li>
</ul>
<h2>Other approaches?</h2>
<p>Please tell us!
<p class="signature">
<a href="http://mfabrik.com/@@zoho-contact-form"><img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/mfabrik-24.png"></a> <a href="http://mfabrik.com/@@zoho-contact-form">Get developers</a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml"><img valign="middle" src="http://www.feedburner.com/fb/images/pub/feed-icon16x16.png" alt="" style="vertical-align:middle;border:0"/></a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml">Subscribe mFabrik blog in a reader</a> <a href="http://twitter.com/mfabrik"> <img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/twitter-24.png"></a> <a href="http://twitter.com/moo9000">Follow me on Twitter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2011/03/15/everyone-loves-and-hates-console-log/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>domgen &#8211; Creating HTML with Javascript without DOM API</title>
		<link>http://blog.mfabrik.com/2010/09/02/domgen-creating-html-with-javascript-without-dom-api/</link>
		<comments>http://blog.mfabrik.com/2010/09/02/domgen-creating-html-with-javascript-without-dom-api/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 12:43:41 +0000</pubDate>
		<dc:creator>Jussi Toivola</dc:creator>
				<category><![CDATA[browser]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://blog.mfabrik.com/?p=730</guid>
		<description><![CDATA[Tired of using Javascript DOM API for generating HTML dynamically? Meet domgen. domgen is a tool for easy dynamic content generation via Javascript. It generates DOM elements from dictionary specification similar to HTML and eliminates the need for cumbersome DOM Javascript API. domgen uses a simple specification to generate the HTML. In some cases it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>Tired of using Javascript DOM API for generating HTML dynamically? Meet <a href="https://bitbucket.org/mfabrik/domgen">domgen</a>. domgen is a tool for easy dynamic content generation via Javascript. It generates DOM elements from dictionary specification similar to HTML and eliminates the need for cumbersome DOM Javascript API.</p>
<p>domgen uses a simple specification to generate the HTML. In some cases it&#8217;s more reliable to use DOM API to generate HTML instead of using innerHTML. We have had problems especially with iPhone when using innerHTML.<br />
See for example <a href="http://pastebin.com/LLk3J0iH">http://pastebin.com/LLk3J0iH</a> or google &#8220;iPhone innerHTML&#8221; for more info. In fact, innerHTML is not even part of the HTML standard even though it exists on every browser.</p>
<p>So if you want to add dynamic HTML properly, you should use the <a href="http://www.w3schools.com/jsref/dom_obj_all.asp">Javascript DOM API</a>. Consider the following short HTML where the contents inside body had to be generated:</p>
<pre>&lt;body&gt;
    &lt;div id="mydiv"&gt;my div&lt;/div&gt;
&lt;/body&gt;</pre>
<p>Using Javascript DOM API:</p>
<pre>// Get the body tag
var body = document.getElementsByTagName("body")[0];
// Create 'div' element
var mydiv = document.createElement("div");
mydiv.setAttribute("id", "mydiv");
mydiv.innerText = "my div";
// Attach the div to body
body.appendChild(mydiv);</pre>
<p>And using domgen:</p>
<pre>var spec = [
    'div',
    {
        id : 'mydiv',
        _innerText : 'my div'
    }
];
domgen.generate( domgen.get("body")[0], spec);
// or with jQuery
domgen.generate( $("body")[0], spec);</pre>
<p>To me, domgen seems a lot easier to read and work with. Get code and more examples here: <a href="https://bitbucket.org/mfabrik/domgen">https://bitbucket.org/mfabrik/domgen</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2010/09/02/domgen-creating-html-with-javascript-without-dom-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>To gzip or not to gzip CSS and Javascript?</title>
		<link>http://blog.mfabrik.com/2010/04/12/to-gzip-or-not-to-gzip-css-and-javascript/</link>
		<comments>http://blog.mfabrik.com/2010/04/12/to-gzip-or-not-to-gzip-css-and-javascript/#comments</comments>
		<pubDate>Mon, 12 Apr 2010 10:38:14 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[plone]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[bandwidth]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[decompression]]></category>
		<category><![CDATA[gunzip]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[latency]]></category>
		<category><![CDATA[speed]]></category>

		<guid isPermaLink="false">http://blog.mfabrik.com/?p=460</guid>
		<description><![CDATA[Dear Lazyweb, Is it wise to gzip static resources (javascript and CSS) before sending them to client? The opinion of Internet seems to be divided GZip decompression takes too much time at the client end and thus it is not wise (latency at the clients end) Bandwidth save is enough to counter the decompression latency [...]]]></description>
			<content:encoded><![CDATA[<p>Dear Lazyweb,</p>
<p>Is it wise to gzip static resources (javascript and CSS) before sending them to client?</p>
<p>The opinion of Internet seems to be divided</p>
<ul>
<li>GZip decompression takes too much time at the client end and thus it is not wise (latency at the clients end)</li>
<li>Bandwidth save is enough to counter the decompression latency</li>
</ul>
<p>So if we put this to context of</p>
<ul>
<li>Compressed and merged CSS and Javascript files of Plone</li>
<li>Assuming the users are using the state of the art browsers: Safari 4, Chrome, Firefox 3.6 and IE8</li>
<li>Connections are faster than 384 Kbit/s</li>
</ul>
<p>&#8230;and forget&#8230;</p>
<ul>
<li>Recompressing images (GIF, PNG and JPEG) using GZip as there is no notable save</li>
</ul>
<p>should I enable GZip compression on the front-end server (Apache) with disk cache enabled?</p>
<p>Of course, I could do testing and timing myself, but I&#8217;ll simply ask for your experiences first before investing few hours for this. Also, hints how to measure how fast GZip decompression is, are welcome.</p>
<p>Thank you.
<p class="signature">
<a href="http://mfabrik.com/@@zoho-contact-form"><img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/mfabrik-24.png"></a> <a href="http://mfabrik.com/@@zoho-contact-form">Get developers</a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml"><img valign="middle" src="http://www.feedburner.com/fb/images/pub/feed-icon16x16.png" alt="" style="vertical-align:middle;border:0"/></a> <a href="http://feeds.feedburner.com/mFabrikWebAndMobileDevelopment" rel="alternate" type="application/rss+xml">Subscribe mFabrik blog in a reader</a> <a href="http://twitter.com/mfabrik"> <img valign="middle"  src="http://blog.mfabrik.com/wp-content/uploads/twitter-24.png"></a> <a href="http://twitter.com/moo9000">Follow me on Twitter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2010/04/12/to-gzip-or-not-to-gzip-css-and-javascript/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Now hiring (Developer, Helsinki)</title>
		<link>http://blog.mfabrik.com/2010/03/29/now-hiring-developer-helsinki/</link>
		<comments>http://blog.mfabrik.com/2010/03/29/now-hiring-developer-helsinki/#comments</comments>
		<pubDate>Mon, 29 Mar 2010 09:14:31 +0000</pubDate>
		<dc:creator>veikko</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[Business]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://blog.mfabrik.com/?p=438</guid>
		<description><![CDATA[We are looking for a new developer to join our production team in Helsinki, Finland. Check out the details at our web site: http://mfabrik.com/about-us/jobs/developer-helsinki]]></description>
			<content:encoded><![CDATA[<p>We are looking for a new developer to join our production team in Helsinki, Finland. Check out the details at our web site:</p>
<p><a href="http://mfabrik.com/about-us/jobs/developer-helsinki">http://mfabrik.com/about-us/jobs/developer-helsinki</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2010/03/29/now-hiring-developer-helsinki/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cross-platform mobile application development and payments</title>
		<link>http://blog.mfabrik.com/2009/09/30/cross-platform-mobile-application-development-and-payment/</link>
		<comments>http://blog.mfabrik.com/2009/09/30/cross-platform-mobile-application-development-and-payment/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 09:55:30 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[blackberry]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[locationing]]></category>
		<category><![CDATA[payment]]></category>
		<category><![CDATA[series 60]]></category>
		<category><![CDATA[symbian]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[appaccelerator]]></category>
		<category><![CDATA[appstore]]></category>
		<category><![CDATA[bango]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[deviceatlas]]></category>
		<category><![CDATA[fennec]]></category>
		<category><![CDATA[gallery]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[nokia]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[phonegap]]></category>
		<category><![CDATA[pre]]></category>
		<category><![CDATA[rhomobile]]></category>
		<category><![CDATA[sms]]></category>
		<category><![CDATA[titanium]]></category>
		<category><![CDATA[upload]]></category>
		<category><![CDATA[web run-time]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://blog.twinapex.fi/?p=277</guid>
		<description><![CDATA[We have been piloting multi-platform mobile application development and payments in few client projects. Target platforms usually include iPhone, Android, Blackberry and Nokia Series 60. Also there are two notable usual cases which need to be specially handled Image uploads Payments for subscribed content Sounds easy, right? Well it isn&#8217;t&#8230; Below are some notes for [...]]]></description>
			<content:encoded><![CDATA[<p>We have been piloting multi-platform mobile application development and payments in few client projects. Target platforms usually include iPhone, Android, Blackberry and Nokia Series 60. Also there are two notable usual cases which need to be specially handled</p>
<ul>
<li>Image uploads</li>
<li>Payments for subscribed content</li>
</ul>
<p>Sounds easy, right? Well it isn&#8217;t&#8230; Below are some notes for our due diligence work which you fellow developers might find interesting.</p>
<h2>SDKs</h2>
<p>Mobile phone vendors are jealously and don&#8217;t want to co-operate with each other. Building application which works in all handsets is major headache.</p>
<p>We found some reasonable candidates for cross-platform mobile development doing HTML and Javascript. HTML and Javascript pages are converted to native application using a wrapper technology (a.k.a. appaccelerator). Doing Flash Lite or Java ME can be pretty much forgotten nowadays as they won&#8217;t run on the most hyped platform, iPhone. Flash Lite has poor support for anything except content authoring due to primitive and limited APIs. Java ME provides horrible user experience.</p>
<p>(X)HTML is the only common language spoken by mobile phones. Thus, there has been a rise of &#8220;appaccelerators&#8221;, technologies which allow to create mobile applications with HTML(5) and Javascript.</p>
<ul>
<li><a href="http://www.phonegap.com/">Phonegap:</a> iPhone, Android, Blackberry and possibly S60 in the future. <strong>Pluses:</strong> BSD license, very active community. <strong>Minuses:</strong> <a href="http://groups.google.com/group/phonegap/browse_thread/thread/5760d86c91970441/f0305e400b362933#f0305e400b362933">bad documentation, difficult deployment process</a>.</li>
<li><a href="http://www.appcelerator.com/">Titanium</a>: iPhone, Android.<strong> Pluses: </strong>Professional, Apache license. <strong>Minuses:</strong> Too tightly coupled with Appacclerator Inc. company.</li>
<li><a href="http://www.rhomobile.com/">Rhomobile</a>: iPhone, Android, Blackberry, S60, Windows Mobile. <strong>Pluses:</strong> Professional, tries to build open source community, the widest platform support. <strong>Minuses:</strong> Dual licensing and tightly coupled with Rhomobile Inc.</li>
<li><a href="http://www.forum.nokia.com/Technology_Topics/Web_Technologies/Web_Runtime/">Nokia Web-runtime</a>: Nokia S60 and some other Symbian based phones. <strong>Pluses: </strong>Professional, good documentation. <strong>Minuses: </strong>Not open source, impossible to extend, Nokia has little interest to make this cross-platform, Nokia doesn&#8217;t like updating old models and web-runtime is useable only in the latest S60 5th edition models.</li>
<li>Palm Pre supports web applications natively. However Palm Pre application business is still taking a shape.</li>
</ul>
<p>All these wrap the browser component (WebKit) and provide some extra Javascript APIs when your web pages as executed under the application mode.</p>
<ul>
<li>Locationing</li>
<li>Contacts</li>
<li>SMS</li>
<li>Client-side database</li>
<li>and so on&#8230;</li>
</ul>
<p>Rhomobile has little different use cases  from the rest of the bunch as it provides client-side programming using Ruby and less focuses on Javascript/web applications.</p>
<h2>Payments and in-application purchases</h2>
<p>There are four major way to do mobile payments &#8220;inside&#8221; the application for bought content and subscriptions. The price tag on the application itself is left out on this discussion as the application stores themselves take care of it.</p>
<ul>
<li>Credit card</li>
<li>SMS</li>
<li>App Store payment (thus far Apple only)</li>
<li>Direct operator payments &#8211; you have a service provider (Bango) which can directly charge items to the operator phone bill based on handset identification.</li>
</ul>
<p>App Store payment is the most attractive as it provides the best end user experience.  It allows you to use App Store payment mechanism inside the application. It is safe and no need to hassle with external payment providers. However, App Store payment can be used only for content consumed directly inside the application. You cannot use it e.g. for ordering a pizza. I think this might be related to recent EU legislation forbidding SMS payments for services not consumed in the phone itself.</p>
<p>SMS payment is ok for little payments. Operators take big cut of the revenue, generally 30% &#8211; 70% depending on the country. Short code fees usually start from 500€ set-up fee + 500€ / month. SMS cannot be often send as a background, but the user is presented the normal SMS editor which reduces the user experience somehow.</p>
<p>For credit card payments there exists several providers. Credit card has the cheapest entry fees, but the downside is that the user needs to have the credit card. This excludes teenager audience.</p>
<p>Direct operator payments are not very well supported yet globally. Most western operators support them. The operator also takes a big share and the fixed fee is pretty high.</p>
<p>My favorite payment provider thus far is<a href="http://www.bango.com"> Bango</a> which provides credit card payment starting 9€ / mo. and scales up to worldwide SMS payments which cost few grannies per month.</p>
<p>In most cases, the payment experience will not be smooth. You need to open the phone main browser on the payment provider page to do the payment. This usually will close your own application. Rarely you can do the payment inside the application <em>and</em> support multiple platforms. After doing the payment most platforms allow you to close the browse and reopen your application using a special URL handler.</p>
<p><a href="http://en.wikipedia.org/wiki/Mobile_payment">Wikipedia mobile payments</a> page is also useful.</p>
<h2>Image upload</h2>
<p>&lt;input type=&#8221;file&#8221;&gt; won&#8217;t work on iPhone and some other platforms  as those don&#8217;t have user browsable file system. Also the file dialog usually doens&#8217;t have image preview making it useless.</p>
<p>Phonegap has a branch which supports images picking using iPhone&#8217;s own gallery browser.</p>
<p>In any case, there is not yet cross-platform solution for this.</p>
<h2>Future prospects</h2>
<p>In some time-frame we will get rid of the need to wrap HTML applications natively as the web browser applications will support all HTML5 features without extensions and probably have some proprietary extensions for mobile specific features like SMS. We already have had some taste for this:</p>
<ul>
<li>The first taste of this is <a href="http://hacks.mozilla.org/2009/06/geolocation/">Mozilla&#8217;s Fennec mobile browser which has locationing support</a>.</li>
<li>iPhone&#8217;s Safari already supports <a href="http://developer.apple.com/safari/library/documentation/iPhone/Conceptual/SafariJSDatabaseGuide/Introduction/Introduction.html">client-side storage</a> and <a href="http://girliemac.com/blog/2009/01/23/webkit-comparison-on-css3/">CSS3</a>.</li>
<li>All phones have support for dial-in links. The format of the link may vary. <a href="http://deviceatlas.com/">DeviceAtlas</a> is good place to hunt for this information.</li>
<li>Nokia browser supports send SMS links</li>
<li>Nokia browser supports downloadable map markers (to the map application of the phone itself)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2009/09/30/cross-platform-mobile-application-development-and-payment/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>MooTools setOptions() nullifies object references</title>
		<link>http://blog.mfabrik.com/2008/08/19/mootools-setoptions-nullifies-object-references/</link>
		<comments>http://blog.mfabrik.com/2008/08/19/mootools-setoptions-nullifies-object-references/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 00:21:08 +0000</pubDate>
		<dc:creator>Tuukka Mustonen</dc:creator>
				<category><![CDATA[debugging]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mootools]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[solution]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[addressing]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[object]]></category>
		<category><![CDATA[problem]]></category>
		<category><![CDATA[reference]]></category>
		<category><![CDATA[setOptions]]></category>
		<category><![CDATA[ui]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://blog.redinnovation.com/?p=64</guid>
		<description><![CDATA[I bumped up into a problem where the object references where resolved as object copies when I passed them to class instances. That might sound easy to resolve, but unfortunately I was already deep in code and it was difficult to see this. Therefore, here&#8217;s a little explanation for those who are facing the same [...]]]></description>
			<content:encoded><![CDATA[<p>I bumped up into a problem where the object references where resolved as object copies when I passed them to class instances. That might sound easy to resolve, but unfortunately I was already deep in code and it was difficult to see this. Therefore, here&#8217;s a little explanation for those who are facing the same frustrating issue.</p>
<p>Say, you have variable &#8216;a&#8217; and you want to pass it to a MooTools class B instance during creation. In the easiest case you&#8217;d use new B({ myReference: a}) and trust on MooTools&#8217; Class.setOptions() to minify the need of code lines. This is what you should do&#8230; well at least that&#8217;s what I did and in this case it was a mistake.</p>
<p>It turns out that Class.setOptions() merges it&#8217;s arguments to this.options and then takes copy of them via $merge(). That means that any variable references you pass to setOptions() will get copied to this.options and.. well, that&#8217;s it. See lines 1170-1173 in uncompressed version of MooTools 1.2:</p>
<pre>var Options = new Class({
    setOptions: function(){
        this.options = $merge.run([this.options].extend(arguments));</pre>
<p>That effectively nullifies the benefits of Class.setOptions() if you want to pass in variable references..</p>
<p>Here&#8217;s a longer example to clarify (use Firebug):</p>
<pre>  // The most basic MooTools class that implements options
  // ref is a variable meant for pointing at given object
  // (won't do that, however)
  var B = new Class({
    Implements: Options,
    options: {
      ref: null
    },
    initialize: function(options) {
      this.setOptions(options);
    }
  });

  // Ok let's create an instance that we can pass to B
  // It's similar with all sorts of variables
  var A = new Class({
    initialize: function() {
      this.somevar = 'untouched';
    }
  });
  var a = new A();

  // Create an instance of B and give it somevar as reference
  var b = new B({ ref: a });

  // prints out "untouched" as should
  console.log(b.options.ref.somevar);

  // Let's change the variable (direct access, bad)
  a.somevar = "changed";

  // b's reference should still point to a, right?
  // In that case the following should print "changed",
  // but because our reference object was copied instead
  // of retaining reference to it, we just get "untouched"
  console.log(b.options.ref.somevar);</pre>
<p>I don&#8217;t know why MooTools wants to make a copy of arguments in setOptions() &#8211; propably for performance reasons.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2008/08/19/mootools-setoptions-nullifies-object-references/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Catching silent Javascript exceptions with a function decorator</title>
		<link>http://blog.mfabrik.com/2008/08/19/catching-silent-javascript-exceptions-with-a-function-decorator/</link>
		<comments>http://blog.mfabrik.com/2008/08/19/catching-silent-javascript-exceptions-with-a-function-decorator/#comments</comments>
		<pubDate>Mon, 18 Aug 2008 22:08:59 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[document]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[event handler]]></category>
		<category><![CDATA[exception]]></category>
		<category><![CDATA[failure]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[onready]]></category>
		<category><![CDATA[silent]]></category>

		<guid isPermaLink="false">http://blog.redinnovation.com/?p=61</guid>
		<description><![CDATA[The one utterly annoying thing with the otherwise excellent Firefox/Firebug combo is that some exceptions are let silently through without being end up to be visible in the Firebug console. This makes debugging very difficult, unless you are aware of the phenomenon. I am not sure whether this is caused by some internal Firefox logic [...]]]></description>
			<content:encoded><![CDATA[<p>The one utterly annoying thing with the otherwise excellent Firefox/Firebug combo is that some exceptions are let silently through without being end up to be visible in the Firebug console. This makes debugging very difficult, unless you are aware of the phenomenon. I am not sure whether this is caused by some internal Firefox logic flow, since IE + Visual Web Developer doesn&#8217;t seem to be affected by this.</p>
<p>Since this problem pops up constantly, I decided to create an easy way to deal with the situation. I decorate all functions which made have silent exceptions (e.g. one called from document load event) with a custom logger function which will first log the exception and then rethrow it.</p>
<p>Thus instead of writing (JQuery example)</p>
<pre>myfunction() {
    // crash here
    var i = foobar; // missing variable foobar
}

$(document).ready(myfunction);</pre>
<p>write</p>
<pre>myfunction() {
    // crash here
    var i = foobar; // missing variable foobar
}

$document.ready(logExceptions(myFunction));</pre>
<p>or</p>
<pre>// myFunction can be bind to many events and exceptions are logged always
myfunction = logExceptions(function() {
  // crash here
    var i = foobar; // missing variable foobar
});

$document.ready(logExceptions(myFunction));</pre>
<p>The Javascript code for the decorator:</p>
<pre>/**
 * Enhancd Javascript logging and exception handler.
 *
 * Copyright 2008 Red Innovation Ltd.
 *
 * @author Mikko Ohtamaa
 * @license 3-clause BSD
 *
 */

// Browser specific logging output initialization
// Supports Firefox/Firebug. Other (Opera) can be hooked in here.
if(!console) {
	// Install dummy functions, so that logging does not break the code if Firebug is not present
    var console = {};
    console.log = function(msg) {};
    console.info = function(msg) {};
    console.warn = function(msg) {};
} else {
    // console.log provided by Firefox + Firebug
}

/**
 * Try print human digestable exception stack trace to Firebug console.
 *
 * http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Error
 *
 * @param e: Error
 */
function printStackTrace(e) {

	var msg = e.name + ":" + e.message;

	if (e.fileName) {
		msg += " at " + e.fileName + ":" + e.lineNumber;
	}
	console.log(msg);

	if (e.stack) {
		// Extract Firefox stack information. This tells how you ended up
		// to the exception in the first place. I didn't find
		// instructions how to parse this stuff.
		console.log(e.stack);
	}
}

/**
 * Decorate function so that exceptions falling through are printed always.
 *
 * Returns a decorated function which will be used instead of the normal function.
 * The decorated function has preplaced try ... catch block which will not let
 * through any exceptions silently or without logging. Even though there is an
 * exception it is normally throw upwards in the stack after logging.
 *
 * @param func: Javascript function reference
 */
function logExceptions(func) {

	var orignal = func;

	decorated = function() {
		try {
			orignal.apply(this, arguments);
		} catch(exception) {
			printStackTrace(exception);
			throw exception;
		}
	}

	return decorated;
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2008/08/19/catching-silent-javascript-exceptions-with-a-function-decorator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Verifying Javascript files with JSLint from Eclipse IDE</title>
		<link>http://blog.mfabrik.com/2008/03/27/verifying-javascript-files-with-jslint-from-eclipse-ide/</link>
		<comments>http://blog.mfabrik.com/2008/03/27/verifying-javascript-files-with-jslint-from-eclipse-ide/#comments</comments>
		<pubDate>Thu, 27 Mar 2008 13:10:08 +0000</pubDate>
		<dc:creator>Mikko Ohtamaa</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[ext js]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[jseclipse]]></category>
		<category><![CDATA[jslint]]></category>
		<category><![CDATA[rhino]]></category>
		<category><![CDATA[verify]]></category>

		<guid isPermaLink="false">http://blog.redinnovation.com/2008/03/27/verifying-javascript-files-with-jslint-from-eclipse-ide/</guid>
		<description><![CDATA[With Web 2.0, Javascript has gained a great foothold in the web development. Javascript, which was originally indented to be few lines of interactivity here and there, is now used for full-blown UI frameworks like Ext JS and Dojo. Because its toy background, Javascript is not the easiest language to debug. Also, the lovely phenomenon [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.redinnovation.com/wp-content/themes/redinnovation/images/naama4.jpg" align="left" height="154" hspace="10" vspace="10" width="128" />With Web 2.0, Javascript has gained a great foothold in the web development. Javascript, which was originally indented to be few lines of interactivity here and there, is now used for full-blown UI frameworks like <a href="http://www.extjs.com">Ext JS</a> and <a href="http://www.google.com/url?sa=t&amp;ct=res&amp;cd=1&amp;url=http%3A%2F%2Fdojotoolkit.org%2F&amp;ei=QYfrR52DBp_8wwHn9MEV&amp;usg=AFQjCNGA7YR8rGVmo1u_5-t7HJyhmL1beA&amp;sig2=PqVEAHMMcKrl91DUl8NGxA">Dojo</a>. Because its toy background, Javascript is not the easiest language to debug. Also, the lovely phenomenon known as browser wars has ensured that professional Javascript  development is PITA due to browser incompatibilities &#8211; It seconds the Symbian C++ embedded programming if you know what I mean.</p>
<p>Javascript is executed run-time. Thus, any errors cannot be cached until the code is run. <a href="http://www.jslint.com/">JSLint</a> is a verifier tool which checks Javascript syntax  offline. Of course, it cannot detect application logic errors, but it makes sure that you don&#8217;t have cross-browser compability problems in your Javascript syntax. Maybe the most famous of these problems is  the extra comma before the list termination which is ok for Firefox, but kills the page on Internet Explorer.</p>
<p>Some argue that <a href="http://dean.edwards.name/weblog/2006/06/jslint/">this does not really catch bugs</a> and instead a comprehensive unit-test suite should be used. This might be a requirement for a platform level Javascript library code, but it is often an overkill for your little site with some flashy dialog windows.</p>
<p><strong>Installing JSLint</strong></p>
<p>JSLint itself is written in Javascript. So you need to offline Javascript interpreter to run it. On Linux there exists Rhino. On Ubuntu, <a href="https://bugs.launchpad.net/ubuntu/+source/rhino/+bug/93885">Rhino package is broken</a>. and you need to download the orignal Rhino JAR from <a href="http://developer.mozilla.org/en/docs/Rhino_downloads_archive">here</a> and copy it to <em>/usr/share/java</em>.</p>
<pre>sudo apt-get install rhino # Note https://bugs.launchpad.net/ubuntu/+source/rhino/+bug/93885</pre>
<p>Then  get JSLint offline version from <a href="http://www.jslint.com/rhino/jslint.js">here</a>.</p>
<p><strong>Running JSLint straight from the Eclipse</strong></p>
<p>We use <a href="http://www.interaktonline.com/Products/Eclipse/JSEclipse/Overview/">JSEclipse</a> plug-in in Eclipse for Javascript development. Thus, it is convenient to to execute JSLint directly from the Eclipse IDE.</p>
<p>Drag and drop jslint.js to your project/scripts folder in Eclipse.</p>
<p>Create a new External tool like in the example below.</p>
<p><a href="http://blog.redinnovation.com/wp-content/uploads/2008/03/screenshot-external-tools.png" title="screenshot-external-tools.png"><img src="http://blog.redinnovation.com/wp-content/uploads/2008/03/screenshot-external-tools.thumbnail.png" alt="screenshot-external-tools.png" /></a></p>
<p>Then you can run it by just clicking &#8220;run external tool&#8221; icon. Output comes to the console window.</p>
<p><a href="http://blog.redinnovation.com/wp-content/uploads/2008/03/screenshot-pydev-nurse-source-server-media-js-ui-mapjs-eclipse-sdk.png" title="screenshot-pydev-nurse-source-server-media-js-ui-mapjs-eclipse-sdk.png"><img src="http://blog.redinnovation.com/wp-content/uploads/2008/03/screenshot-pydev-nurse-source-server-media-js-ui-mapjs-eclipse-sdk.thumbnail.png" alt="screenshot-pydev-nurse-source-server-media-js-ui-mapjs-eclipse-sdk.png" /></a></p>
<p><strong>Checking all Javascript files during unit test  </strong></p>
<p><a href="http://blog.redinnovation.com/wp-content/uploads/2008/03/verify_javascript.bash" title="verify_javascript.bash">verify_javascript.bash</a> can be executed from shell and it checks all JS files in your project. This is a nice feature to integrate to your unit test cycle.</p>
<p>Example:</p>
<pre>
$ bash scripts/verify_javascript.bash source/server/media/jssource/server/media/js/jquery.js

Lint at line 11 character 30: Expected '{' and instead saw 'var'.

...</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.mfabrik.com/2008/03/27/verifying-javascript-files-with-jslint-from-eclipse-ide/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

