Posts Tagged “programming”

Google Analytics - How to log duration of a single page visit

So no doubt you are here because of Google Analytics showing you Avg Session Duration being 00:00:00 and Bounce Rates of 100%. You are thinking, surely people aren't that turned off my site that they are leaving instantly.Google Analytics calculates a users time on your site (session duration) by comparing the time from the first page view to the second. This is fine for sites where people browser content, most of the views will be accurate. But for sites with a variety of information in single pages, like blogs, you may be like me and find people enter 1 page, find their answer and leave. But without knowing how long someone spent reading your page you don't really know if they took 1 look and figured it wasn't right for them, or if they spent 15min carefully reading everything.Read more...

Jekyll - Inline include SASS/SCSS to HTML

Playing around with some mobile first, basic design using Jekyll and Github for my new blog. I wanted to have the critical CSS inlined into the HTML for speedy delivery.So I created a critical.scss file with my mobile first styles in it, and figured out the code below to include them in the head.htmlRead more...

Greasemonkey script for RealEstate.com.au - Hide previously viewed properties from map

Looking for a new house, and got sick of having to wade through the same listings every few days. So this script stops pins showing up in the map if I've already viewed them on the map.Previously viewed properties are stored in your browsers local storage, so easiest way to clear is pasting the code below into the console while on RealEstate.com.au
localStorage.setItem('viewedProps', '');
Can get script at [https://gist.github.com/sacah/49cb7073605513af76a1#file-hide-previously-viewed-properties-realestate-com-au-user-js](https://gist.github.com/sacah/49cb7073605513af76a1#file-hide-previously-viewed-properties-realestate-com-au-user-js)

Linux Batch Thumbnail Creation of folder with subdirectories

I have a RaspberryPi with a 750gb attached HDD, on this drive I store a folder called Photos, it contains many sub-directories with photos in them.I wanted to create a new directory that had the same structure of Photos, but all the images are smaller thumbnailed versions.To accomplish this I tried a number of programs and scripts I found online for linux, but most didn't handle sub-directories, I then tried to find programs on Windows that would do this across the network, but they either didn't handle sub-directories or didn't handle errors in network traffic and would bomb out.Read more...

Dynamically adding aria-describedby using JavaScript

Just a quick one to let others know what I've found, while it seems many of the ARIA tags work happily when added dynamically, aria-describedby will only work if it's present when the DOM is rendered, after that screen readers just won't see it.The simple ways around this seem to be adding random unique aria-describedbys to all your elements, then dynamically changing the ID of what you want to point too.Or use a global aria-live element that you change the text in to match the text you would have pointed to with aria-describedby.

Uploading multiple LCOV and JUnit XMLs for the same source to Grunt-Karma-Sonar

I recently needed to upload 2 LCOV files, and 2 JUnit XML files up to Sonar. The problem was both LCOV and JUnit XMLs covered the same JS source files, so if I'd configured grunt-karma-sonar like normal, with the JS source path in the 'path' option, Sonar would throw an error about duplicate source files.So I comment out the 'path' option for the second set, but then the LCOV file has the wrong path when it gets uploaded to Sonar, meaning Sonar doesn't count those coverage results.Read more...

Using perceptual diffs to spot mistakes during web development

So I started this a month ago when I saw a video from Google about pdiffs, then got promptly distracted on other projects and games...

Then today saw a post from BBC about this sort of thing and figured I'd post with how far I've gotten, and see if it spurs me to do more testing on how best this can be displayed.

Basically, you want an easy way to check for style/layout changes. Automating this is difficul, ttime consuming, and eye balling it can all look the same after a few iterations.Read more...

jQuery Selector Performance Monitor - jqspm

In my job as a contract front end developer, I work with large existing code bases. Many times I've started at a company and been asked, "Why does Page X take so long to load?".

There are plenty of tools to figure out other aspects of the pages load/render time, but one I haven't found is to see if there are any poorly written jQuery selectors. An actual example I've found in production code was a selector taking 8.5 seconds on an iPhone 5, tweaking the selector, it now takes 50ms.Read more...

TimeZones with Javascript

So I originally wanted to make a TimeZone selector similar to most OSes, you know, the world map with cities visible and you can select the one in your time zone. The thing I didn't want to do with this was all the work of building and maintaining a DB of cities and their GMT offset along with daylight saving rules.

So I looked around and found a time zone database, now hosted at http://www.iana.org/time-zones. I downloaded these and started writing my JS library to parse the list and generate the rules for all the time zone info. And thus jsTimeZone was born.Read more...

Facebook Javascript API - Post to wall - FB JS SDK

Working with the Facebook JS SDK I was having problems using the FB.ui to log the user is, and post a message to their wall. Main error was 'Permission denied to access property 'Arbiter'.'. I tried many different things such as developing this on a website that could be accessed from external sources, but the problem wouldn't go away.


So I wrote some code that used FB.login and FB.api, though after login/permission acceptance it would leave the XD Proxy window open on a blank page. Below is my code which will handle the XD Proxy window, login, permission acceptance and post to their wall, even on your local environment without external sources being able to access your site.


First we install the FB API


<script>
window.fbAsyncInit = function() {
FB.init({
appId : facebookAppId,
channelUrl : 'http://'+ window.location.host +'/channel.html',
status : true,
cookie : true,
xfbml : true,
oauth : true
});
};

(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
</script>


Next we want to setup the function to handle the login/permissions.


function FBShare(title, link, picture, msg, caption) {
FB.login(function(data) {
postFBMsg(title, link, picture, msg, caption);
}, {scope: 'publish_stream'});
}


Here I call FB.login, setting scope to publish_stream which once the user is logged in will ask for permission to allow my app to publish to their wall.
Once login is complete and they have accepted my permissions, we call postFBMsg.


function postSocialMsg(title, link, picture, msg, caption) {
var body={
message: msg,
picture: picture,
link: 'http://'+ window.location.host +'/'+ link,
name: title,
caption: caption
}

FB.api('/me/feed', 'post', body, function(response) {
if (!response || response.error) {
// Error
} else {
// Successful
}
});
}


Here I set the body var to contain our Facebook Wall Post details, we have the title(Don't Worry Be Happy) which will be linked to link, we have picture(Guy Sebastian pic), msg(Wall Post Message) which will appear under the Username(John Smith), title and caption(Guy Sebastian) which will appear under our Message to the right of the picture. If no Caption is sent it displays the link URL instead.


The final piece to our puzzle is to handle the closing of the XD Proxy window after login. It posts back to the calling window after actions are performed, I setup an event to capture these messages and close the window once it receives one. If you already are using postMessage between windows, you'll need to setup a conditional statement to only close the window if it's a Facebook message.


 $(window).bind('message', function(e) {
e.originalEvent.source.window.close();
});


So once we get a message via postMessage we close the window of the message sender.


This is how I'm doing it in my local development environment, inaccessible to the outside world, if you spot and flaws, or know of a better way of doing things please leave a comment.

Firefox 9.0.1 Error: uncaught exception: TypeError: args.shift() is null

So looking at a site we're developing this morning in FF 9.0.1 and some pages didn't work on some peoples machines, though worked fine on mine. After installing Firebug to see what was going on the pages would work fine.

I uninstalled Firebug and looked at the Firefox Error Console to find the following error.
Error: uncaught exception: TypeError: args.shift() is null


Was a weird one, after much poking around I found it's a poor handling of arguments supplied to console.log, hopefully this is a bug in FF9.0.1 and will be corrected in the next release. For now to quickly get things working I've just extended my console.log handler to set console.log=function() {} to cancel console.log functionality until it's fixed.

If it's not addressed in future versions I'll have to look into it further to detect if Firebug isn't active and do some alternate handling for development.

To work around this I've changed my code to this
if(window.location.search!='?debug=1') {
top.console.log=function() { }
}

Now I just add ?debug=1 to URL and it uses built in console log so I can manage when it comes on.

Hope this helps, if you have further info please leave a comment.

Filter Keys jQuery Plugin

To help users fill in a form, you can filter out keys you don't want them to try and use. If it's a numeric field, supply the data-filterkeys='[0-9]' and they can only enter numbers. If it's a price, use data-filterkeys='[0-9$\.]' and they can enter numbers and $ and .I have written it to also use a class of .filterkeys on each input, rather than just searching for inputs with a custom attribute, simply because the class search is faster. If you really don't want to have a filterkey class on all inputs requiring the filterkeys functionality, it's an easy change:$('.filterkeys', this)to$('[data-filterkeys]', this)Download from [BitBucket](https://bitbucket.org/sacah/filterkeystrokes/src)

Javascript: Long loops without blocking UI updates

Browsers like to finish running JavaScript before they update the UI, which makes sense when majority of JavaScript is dealing with DOM manipulation.The problem this causes is the UI becoming unresponsive when JavaScript takes too long to execute. Many times it's looping through an array of objects and performing the same operations on each object that causes this the UI to hang.Read more...

Javascript: Format Number, Price, Amount

After looking around at many different number formatting scripts, I figured surely the joy of regular expressions could do this is far fewer lines of code, so off I set and below is my creation. First is the two line function, below that I have put each statement on a new line for ease of explaining what/how it does its formatting.
function formatNumber(number) {
    number=number+'';
    return number.replace(/[^\d\.\-]/g, '').replace(/(\.\d{2})[\W\w]+/g, '$1').split('').reverse().join('').replace(/(\d{3})/g, '$1,').split('').reverse().join('').replace(/^([\-]{0,1}),/, '$1').replace(/(\.\d)$/, '$1'+'0').replace(/\.$/, '.00');
}

formatNumber(-1234.56);
formatNumber(1234567.890);
formatNumber(123.3);
formatNumber('4423897544352423434');
Read more...