0 notes &

Tracking your Crossrider Extension usage using the Google Analytics Universal API

Crossrider extensions are renowned for their ease of development and cross browser compatibility. Google Analytics is synonymous with gathering essential monitoring data for determining the success of a project. By combining them you can gain a real insight into how your extension is being used and measuring user activity.

Google’s Universal Analytics API (UA) allows us to measure unique user activity that was not previously possible using Google’s Classic Analytics API as it was based on cookies that are not natively available in the extension scope.

In this post, we will demonstrate how you can add UA to your extensions and track unique user activity. For the purpose of this demonstration, we will show you how to add Page View and Event Tracking data to pages on which your extension runs.

So let’s get started by creating a new extension (My Extensions > Create New Extension) …

image

and heading over to edit the code page (Edit Code > extension.js).

image

Before we start coding, let’s identify the key requirements for working with the UA API :

1. The API uses either the HTTP (http://www.google-analytics.com/collect ) or HTTPS (https://ssl.google-analytics.com/collect) protocol.

2. The API uses the POST method to send user interaction data (payload).

3. The data collected for UA is sent as a payload object that requires the following parameters in every post:

  • Protocol Version (v) : The protocol version

  • Tracking ID (tid): The tracking ID that distinguishes to which Google Analytics property to send data

  • Client ID (cid): An ID unique to a particular visitor / user. For this demonstration we use the browser specific id of the user who installed the extension (appAPI.appInfo.userId).

  • Hit Type (t): The type of interaction collected for a particular user

For information about payload parameters, see Measurement Protocol Parameter Reference.

Since we will be posting to UA multiple times, for this demo we decided to implement a simple Analytics object that contains the required parameters and a post method. The post method takes an object that describes just the hit data part of the payload (intelligently filling in the required parameters) and uses our appAPI.request.post method to send the data. Additionally, we decided to automatically detect the current page protocol to determine which UA URL to use for posting.

The following code shows how the Analytics object is implemented:

var Analytics = (function () {
  var _internal = {
    // Automatically set the URL according to the page protocol
    url: window.location.protocol +
      ((window.location.protocol.indexOf('https:') === -1) ?
      'www' : 'ssl') + '.google-analytics.com/collect'
    }, _config = {
      // Required UA payload parameters
      trackingId: 'XX-NNNNNNNN-N', // <-- Change to your tracking Id
      clientId: appAPI.appInfo.userId,
      version: 1
    };

  // Methods
  return {
    // Method to post hit to UA
    post: function(payload) {
      // Intelligently fill on required parameters
      payload.tid = payload.tid || _config.trackingId;
      payload.cid = payload.cid || _config.clientId;
      payload.v = payload.v || _config.version;

      // Post payload to UA using our request API
      appAPI.request.post({
        url: _internal.url,
        postData: payload
      });
    }
  };
}());

The rest is simply a matter of using the post method of the Analytics object we created (Analytics.post) at the appropriate times and with the appropriate data. For example, to implement the page view data, just add the following code:

// Post Page View data to UA
Analytics.post({
  t: 'pageview', // <-- Hit Type
  dh: window.location.hostname, // <-- Document Host Name
  dp: window.location.pathname, // <-- Document Path
  dt: $('title').text() // <-- Document Title
});

Similarly, to track when the user clicks the button injected by the extension we use Analytics.post in the button’s click event handler, as follows:

// Make some space for the button
$('body').css({'margin-top': '26px'});
// Inject a button to the page
$('<button id="bua-button">Tracking Event</button>')
  .css({position:'fixed', top:0, left:0})
  .click(function() {
    // Post Event Tracking data to UA
    Analytics.post({
      t: 'event', // <-- Hit Type
      ec: 'click', // <-- Event Category
      ea: $(this).attr('id'), // <-- Event Action -- Button Id
      el: window.location.href, // <-- Event Label
      ev: 1 // <-- Event Value
    });
  })
  .appendTo('body');

Putting it all together, the extension.js file looks like this:

appAPI.ready(function($) {
  var Analytics = (function () {
    var _internal = {
      url: window.location.protocol +
        ((window.location.protocol.indexOf('https:') === -1) ?
          'www' : 'ssl') +
        '.google-analytics.com/collect'
    }, _config = {
      trackingId: 'XX-NNNNNNNN-N', // <-- Change to your tracking Id
      clientId: appAPI.appInfo.userId,
      version: 1
    };
    
    return {
      post: function(payload) {
        payload.tid = payload.tid || _config.trackingId;
        payload.cid = payload.cid || _config.clientId;
        payload.v = payload.v || _config.version;

        appAPI.request.post({
          url: _internal.url,
          postData: payload
        });
      }
    };
  }());
  
  // Post Page View data to UA
  Analytics.post({
    t: 'pageview', // <-- Hit Type
    dh: window.location.hostname, // <-- Document Host Name
    dp: window.location.pathname, // <-- Document Path
    dt: $('title').text() // <-- Document Title
  });
  
  // Make some space for the button
  $('body').css({'margin-top': '26px'});
  // Inject a button to the page
  $('<button id="bua-button">Tracking Event</button>')
    .css({position:'fixed', top:0, left:0})
    .click(function() {
      // Post Event Tracking data to UA
      Analytics.post({
        t: 'event', // <-- Hit Type
        ec: 'click', // <-- Event Category
        ea: $(this).attr('id'), // <-- Event Action -- Button Id
        el: window.location.href, // <-- Event Label
        ev: 1 // <-- Event Value
      });
    })
    .appendTo('body');
});

That’s pretty much all there is to it which, of course, is why using UA with Crossrider is such a winning combination ☺

All that’s left to do is view the data in Google Universal Analytics. For testing purposes, we recommend installing the extension and viewing the generated anaytics in real time. After installing the extension, log in to your Anaytics account and navigate to the real time events monitoring page (Reporting > Real Time > Events). You should see a page with the extension’s injected button on the top left, and as you click the button you can see the results immediately appear in the graph, something like the following:

image

Looking at the event breakdown we can see data organised by the payload posted. Hence it is important to spend time choosing meaningful values to send as this can give you a greater insight into how your customers are using the extension and enable you to make informed business/product development decisions.

image

If you are not already a member: click the following link to join our cross-browser extension development framework.

0 notes &

Introducing Crossrider Developer Marketplace powered by oDesk

image

We are excited to announce the Crossrider Developer Marketplace (powered by oDesk) and the Crossrider Group on oDesk!

Our new service provides a dedicated marketplace where businesses and individuals requiring Crossrider extensions can post jobs for pre-screened Crossrider Developers to apply for.

So why are we partnering with oDesk? It’s simple really, it worked for us when we started growing rapidly and we had to concentrate on scaling our business; we therefore occasionally sent people to oDesk to find skilled developers to work on their extensions built on our development framework. oDesk helped in this respect, by matching people who wanted to build extensions with skilled web developers with JavaScript experience. It worked so well that we now want to make this service available to everyone, and hence the Crossrider-oDesk partnership is born!

If you are a Crossrider developer, head over to oDesk and join our group to market your Crossrider skills and access exclusive job opportunities. Don’t forget to display the Crossrider group in your oDesk profile, so go ahead and add the Crossrider tag to your skills on oDesk.

If you are a business in need of a cross browser extension, go to oDesk today and post a job for free using the Crossrider skill tag as a criteria.

Crossrider Marketplace

You can also head over to the Crossrider Developer Marketplace for a convenient oDesk interface to find your perfect match integrated directly into our site. To get to Crossrider Marketplace, click the Development Center menu and select Marketplace.

image

Here you can comfortably search for oDesk jobs/developers using the provided filtering criteria such as feedback scores, hourly rate, location, etc.

So start now and realize the benefits of using the Marketplace today!

image

Finally, if you don’t already have a Crossrider developer account, sign-up now and open up a world of possibilities in cross browser extension development. 

If you are an experienced Crossrider developer, join our oDesk group, to add Crossrider to your skills and access exclusive job opportunities.

0 notes &

IE11 and Windows 8.1 Update

As you already might know today (October 17, 2013) Microsoft is releasing their first big update for Win8, simply titled as Win8.1. This update will also include an automatic update for Internet Explorer, bringing the latest version of IE to 11.

Besides presenting improvements such as: WebGL support, faster page rendering, better development and debug console etc. IE11 had some internal extension related changes that required modifications to our platform.

As Crossrider strives to always be several steps ahead of these browser version changes, we had already released the required fixes and updates for all the known issues deriving from that change.

image

Helping our developers sleep better at night and not worry about browser version updates is one of our main goals here at Crossrider.

The only change you need to be aware of is regarding specifically the WebRequest API that will not be supported on IE11/Win8.1. (We are working on a solution for this and we will update soon with more news)

Besides this, all your extensions will keep working as usual and there is no further action required on your end.

If for some reason you do encounter any issue with this latest update or if you have any further questions about this change then please don’t hesitate to contact support@crossrider.com.

The Crossrider Team

Filed under crossrider ie11 win8.1 microsoft internet-explorer

0 notes &

Developing Crossrider Extensions using Sublime Text

image

Today, we are going to introduce to our developers a new and very cool Crossrider API snippets created to make coding extensions using Sublime Text 2 a breeze.

Have you ever wanted to develop Crossrider extensions using your preferred IDE? Missing the Crossrider IDE’s intellisense technology that simplifies coding using our API methods and remembering method parameters? If Sublime is your preferred IDE, there’s no reason to miss out any more.

Our amazing team has put together Sublime snippets, smart templates that insert text for you saving yourself tedious typing and remembering all those parameters. And they couldn’t be simpler to use, simply install the snippets and follow the instructions for using them.

Give it a try and see for yourself how easy and useful they are. If you like them, why not create some for your preferred IDE, send them to us, and we’ll share them with the Crossrider community.

Using the Snippets

Using our snippets is natural and convenient. They automatically appear (like intellisense) as you type our API methods in JavaScript (.js) files.

image

Let’s see it in action. Open a file (e.g. test.js) and start typing our snippet keyword for appAPI.ready (ready). Notice the keyword-sensitive dropdown that appears as you type the keyword, and press Enter or Tab to insert the snippet.

image

Now let’s take a look at how we can speed up keyword searches using a neat Sublime feature that enables you to search snippets by typing ahead. For example, to speed up searching for particularly long keywords such as dbSetFromRemote that can be laborious to type, you can speed up the search by typing significant letters from the keyword such as dbsr.

Note: Keyword searches must always start with the first letter of the keyword.

image

Finally, once the snippet is inserted, you can use Tab to jump between predefined placeholders in the snippet code making it easy for you to customize the code.

Installing Snippets

For your convenience we uploaded the snippets to GitHub, so feel free to use it, tailor it, fork it and contribute back to the project.

On with the installation instructions. First, clone (git clone) or download the project, then locate your Sublime user packages folder, copy the downloaded CrossriderSnippets folder to the user packages folder, and restart Sublime for the changes to take effect.

Tip: The easiest way to find the location of the user packages folder is to create a new snippet (Tools -> New Snippet), attempt to save it making note of the save folder (by default, the user packages folder), and then cancelling the save.

image

Happy coding :)

Filed under crossrider sublime ide developers

0 notes &

Creating a Facebook Notifier Extension in Minutes using Crossrider [SCREENCAST]

Today, we are going to show you how fast and easy it is to create a cross-browser extension using the Crossrider platform and API. In this screencast, we will build a Facebook Notifier in matter of minutes.

The extensions basic functionality is to monitor a user’s Facebook notifications and to display new notifications whenever they are received regardless of which page the user is viewing.

The extension works by obtaining the notifications URL feed and periodically monitoring it by checking for new items. When new items are detected, the extension’s button is updated to indicate the number of new messages and display a notification with the latest message.

Watch the following video to see how easy it is to take the concept and build a fully functioning extension quickly and easily: (You can find the screencast’s full code after the video)

Give it a try and see for yourself why our platform is so popular amongst extension developers!

Finally, you are invited to check our Facebook Notifier Demo Extension and extend it to do more cool things. (Get started quickly by cloning the demo extension from the IDE).

Extension Code

extension.js:

appAPI.ready(function($) {
  // Check that we are on the correct page to extract the feed URL
  if (appAPI.isMatchPages('facebook.com/notifications')) {
    // Check that we haven't already saved the URL
    if (appAPI.db.get('notificationsRss') === null) {
      // Extract the URL and save it to the local database
      appAPI.db.set('notificationsRss',
        'http://www.facebook.com' +
        $('a:contains("RSS")').attr('href')
      );
    }
    // Send message to background to reset button
    appAPI.message.toBackground({ action: 'resetButton' });
  }
  
  // Message listener to receive request to display a notification
  appAPI.message.addListener(function(msg) {
    // If the message is to display the notification
    if (msg.action === 'notify') {
      // Display notification
      appAPI.notifier.show({
        'name':'Facebook-Notifications',
        'title':'Facebook Notifications',
        'body':msg.item,
        'link':msg.link,
        'theme':'facebook',
        'position':'bottom-left',
        'close':false,
        'sticky':false,
        'fadeAfter':5,
        'width':'200px',
        'closeWhenClicked':true
      });
    }
  });
});

background.js:

appAPI.ready(function($) {
      // Set the button icon
      appAPI.browserAction.setResourceIcon('icon.png');
      // Set the the button click event handler
      appAPI.browserAction.onClick(function() {
        // Open the notification page
        appAPI.openURL('http://www.facebook.com/notifications', 'tab');
      });
      
      // Message listener to receive request to reset button
      appAPI.message.addListener(function(msg) {
        // If the message is to reset the button
        if (msg.action === 'resetButton') {
          // Reset the button counter
          appAPI.db.set('badgRssCount', 0);
          // Reset the button badge
          appAPI.browserAction.removeBadge();
        }
      });
      
      // Define and get the RSS URL from the local database
      var notificationsRss = appAPI.db.get('notificationsRss');
      // Periodically perform the callback function, every 5 seconds
      setInterval(function() {
        // Get current RSS URL from local database
        notificationsRss = notificationsRss || appAPI.db.get('notificationsRss');
        
        // Process the notitications feed to find new content
        if (notificationsRss) {
          // Get the feed content (XML)
          appAPI.request.get({
            url: notificationsRss,
            onSuccess: function(response) {
              // Define local variables
              //   items: Extract array of items from response
              //   rssCount: Notification counters from response
              //        and local database
              var items = $('item', $(response)),
                rssCount = {
                  curr: items.length,
                  badg: appAPI.db.get('badgRssCount') || 0,
                  prev: appAPI.db.get('prevRssCount') || items.length
                };
              
              // If there are more items in the response than previously
              if (rssCount.curr > rssCount.prev) {
                // Update badge counter
                rssCount.badg = rssCount.curr - rssCount.prev + rssCount.badg;
                // Update button badge
                appAPI.browserAction.setBadgeText(rssCount.badg + '', [255,0,0,255]);
                // Save updated badge count to local database
                appAPI.db.set('badgRssCount', rssCount.badg);
                // Extract text of latest notification
                var itemText = items.html().match(/<\!\-\-\[CDATA\[<a href\S+?-->(.+?)\]\]>/)[1];
                // Send a message to the active tab with the details
                // of the latest ticket to display a notification
                appAPI.message.toActiveTab({
                  action: 'notify',
                  item: itemText,
                  link: itemText.match(/.*?href="(.+?)".*/)[1]
                });
              }
              // Save updated previous count to local database
              appAPI.db.set('prevRssCount', rssCount.curr);
            }
          });
        }
      }, 5 * 1000);
    });

Filed under crossrider javascript api extensions browser extension

1 note &

From Bookmarklet to Extension in just 5 Minutes

Bookmarklets are short unobtrusive JavaScript commands stored as a bookmark that extend a browser’s functionality. They are great for performing one-click tasks such as posting information to Tumblr, Facebook, Twitter, or querying a search engine, changing the appearance of a page, and much more (see Our favorite bookmarklets).

Have you ever wanted to take the one-click concept a step further and access the same bookmarklets in other ways? In this post, I will demonstrate how you can create cross-browser extensions that install a bookmarklet (Share on Tumblr) that can be activated in any or all of the following ways:

  • Using a browser button
  • Using a bookmark (default)
  • Using the context menu
  • Using a keyboard shortcut

In general, bookmarklet scripts are either short self-contained scripts or they inject a script tag to download code from a remote location. Tumblr uses the first variety, so let’s navigate to their bookmarklet installation page, inspect the Share on Tumblr link element, and grab the code.

image

Notes:

  • When extracting the bookmarklet code, make sure to copy only the actual bookmarklet code since only bookmarks require the javascript: prefix and void(0) suffix.
  • When the bookmark is of the second variety (downloads script from remote location), you simply need to take note of the remote URL.

Now that we have the bookmarklet code, let’s head over to crossrider.com and prepare the building blocks for our extension. We’ll start by (1) creating a new extension, (2) adding the browser buttons feature, (3) uploading the button icon to the resources of the extension, (4) adding the bookmarklet.js resource, (5) pasting the bookmarklet code, and (6) adding the bookmarks plugin.

(1) My Extensions > Create New Extension

image

(2) Settings > Browser Buttons [Turn on Chrome, Firefox, and IE]

image

(3) Edit Code > Resources > Create > Upload [Upload button icon]

image

(4) Edit Code > Resources > Create > Javascript [Create bookmarklet.js file]

image

(5) Edit Code > bookmarklet.js [Add bookmarklet code]

image

(6) Edit Code > Plugins > Add Plugins > Bookmarks [Add bookmarks plugin]

image

Now that the building blocks are in place, let’s concentrate on the code. In our extension we have two types of actions we perform, extending the browser (adding buttons, context menus, and bookmarks) and interacting with the page. The code for these actions must run in their respective scopes, the background scope for extending the browser and the extension page scope for interacting with the page.

Let’s start with the background scope code by adding the title variable that will be used for button tooltips, context menu and bookmarks.

var title = 'Share on Tumblr';

We’ll use the appAPI.browserAction API is used to configure the button:

appAPI.browserAction.setResourceIcon('icon.png'); // Set the button icon
appAPI.browserAction.setTitle(title); // Add the button tooltip
appAPI.browserAction.onClick(runBookmarklet); // Add the onclick event handler

the appAPI.contextMenu API to add a command to the context menu:

appAPI.contextMenu.add('inject-bookmaklet', title, runBookmarklet);

and the appAPI.bookmarks API to add a bookmark if one doesn’t already exist:

appAPI.bookmarks.searchByTitle(title, function(nodes) { // Search for existing bookmark
  if (nodes && nodes.length === 0) { // If existing bookmark not found
    appAPI.bookmarks.getToolbarFolder(function(node) { // Get the bookmarks toolbar
      appAPI.bookmarks.create({ // Create a new bookmark
        title: title, // The bookmark label
        url: urlBookmarklet(), // Returns the bookmarklet as a URL
        parentFolder: node
      });
    });
  }
});

Now, Since the bookmarklet code must run in the page scope and the browser buttons / context menus must be defined in the background scope, we define their callback functions using the appAPI.message API to pass a message to the extension scope requesting that it runs the bookmarklet code.

function runBookmarklet() {
  appAPI.message.toActiveTab({action: 'runBookmarklet'}); // Send message to active tab
}

Lastly for the background scope, the urlBookmarklet function loads the bookmarklet code from the resources file and returns the code wrapped in the javascript: prefix and void(0) suffix required to run as a URL.

function urlBookmarklet() {
  return 'javascript:BOOKMARKLET;void(0);' // Wrap the bookmarklet code
    .replace('BOOKMARKLET', appAPI.resources.get('bookmarklet.js'));
}

Putting it all together, our background code looks like this:

appAPI.ready(function() {
  var title = 'Share on Tumblr';

  appAPI.browserAction.setResourceIcon('icon.png');
  appAPI.browserAction.setTitle(title);
  appAPI.browserAction.onClick(runBookmarklet);

  appAPI.contextMenu.add('inject-bookmaklet', title, runBookmarklet);

  appAPI.bookmarks.searchByTitle(title, function(nodes) {
    if (nodes && nodes.length === 0) {
      appAPI.bookmarks.getToolbarFolder(function(node) {
        appAPI.bookmarks.create({
          title: title,
          url: urlBookmarklet(),
          parentFolder: node
        });
      });
    }
  });

  function runBookmarklet() {
    appAPI.message.toActiveTab({action: 'runBookmarklet'});
  }

  function urlBookmarklet() {
    return 'javascript:BOOKMARKLET;void(0);'
     .replace('BOOKMARKLET', appAPI.resources.get('bookmarklet.js'));
  }
});

Moving on to the extension code, we’ll start by adding a listener to handle requests to run the bookmarklet. When a request is received, the handler calls the runBookmarklet function.

appAPI.message.addListener(function(msg) { // msg is the received data
  if (msg.action === 'runBookmarklet') { // Request to run the bookmarklet
    runBookmarklet(); // Call function to run the bookmarklet
  }
});

Next, we’ll use the appAPI.shortcut API to add the code to run the bookmarklet using a keyboard shortcut (Ctrl+Alt+B):

appAPI.shortcut.add("Ctrl+Alt+B", runBookmarklet, {
  'type':'keydown',
  'propagate':true,
  'disable_in_input':true,
  'target': document
});

And lastly for the extension page scope, the runBookmarklet function loads the bookmarklet code from the resources file and runs it in the extension scope.

Note: The behavior of Bookmarklets that open popups depends on browser implementation.

function runBookmarklet() {
  appAPI.resources.includeJS('bookmarklet.js'); // Load and run bookmarklet
}

Putting it all together, our extension page code looks like this:

appAPI.ready(function($) {
  appAPI.message.addListener(function(msg) {
    if (msg.action === 'runBookmarklet') {
      runBookmarklet();
    }
  });

  appAPI.shortcut.add("Ctrl+Alt+B", runBookmarklet, {
    'type':'keydown',
    'propagate':true,
    'disable_in_input':true,
    'target': document
  });

  function runBookmarklet() {
    appAPI.resources.includeJS('bookmarklet.js');
  }
});

All that’s left to do is to save and install the extension. Now you a free to use the bookmarklet in the following ways:

Using a browser button
image

Using a bookmark (default)

image

Using the context menu

image

Give it a try and see for yourself why our platform is so popular!

Finally, you are invited to try our Tumblr bookmarklets demo extension and rise to the challenge of making extensions of our favorite bookmarklets. Get started quickly by cloning the demo extension.

Edit Code > image

If you are not already a member: click the following link to join our cross-browser extension development framework.

Our favorite bookmarklets

  1. Pinterest
  2. Evernote
  3. Tweet this
  4. Facebook share
  5. Posterous
  6. Xray
  7. Firebug Lite
  8. Gmail this
  9. Readability
  10. Printliminator
  11. PageZipper

2 notes &

Coding.fm - The Making Of

Got “coders-block”? Feeling lonely in your home office? Want to sound like you’re busy coding away when you’re actually taking a break?

Our fun little project, coding.fm brings the sound of coding to your computer. And judging by the feedback so far it’s surprisingly effective at motivating, calming and making you feel like you’re coding in a team.

Check out feedback from:

Inspired by raining.fm we wanted coders out there to know that we’re with them through the lonely nights, busy hackathons and even when you’re having a rough day. There are 3 different sounds that reflect that: Monday Morning Coding, Hackathon Coding, and Angry Dev Coding.

Sounds were recorded in the Crossrider office with an iphone and then loaded onto Soundcloud.

We plan to add more sounds. If you’ve got a sound you think we should add Tweet us or add a comment below.




How To Use Crossrider To Code Browser Extensions In Minutes

Crossrider is a cloud-based JavaScript framework for creating cross browser extensions.

The way it works is very simple; write one JS code for an extension that works on all browsers (Chrome, Firefox, IE, and Safari).

A powerful API, online IDE, and tools make sure you code faster, manage better and even monetize your extension. Learn more

Filed under coding developers LOL

1 note &

6 Web Development Extensions You Should Be Using (But Aren’t)

As developers we’re relying on web development tools more than ever before. And the more we depend on them the smarter and more effective they’re becoming.

A large chunk of tools we depend on are browser extensions. And with an endless array of them to choose from, (Google Chrome has over 50K), are you finding the best ones out there?

Of course, we all know and use a handful of the most popular extensions available but there are many that you’re probably not aware of and really should be using to boost your web development skills and lighten your coding load.

Below are 6 browser extensions you probably haven’t come across and must make room for in your web development toolkit:

1. JSON view

We all know how frustrating it is to have to download JSON files in order to view them. With the JSONView extension you can view a JSON file in your browser without having to download it.

The document is formatted, highlighted, plus arrays and objects can be collapsed. So, even if the JSON document contains errors, JSONView will still show the raw text.

Once you’ve got JSONView installed, check out http://jsonview.com/example.json to see the extension in action!

Get it: https://chrome.google.com/webstore/detail/chklaanhfefbnpoihckbnefhakgolnmc


2. Live Reload

Reloads the page automatically when file changes are made, except for CSS and JavaScript file changes.

When you’re busy coding away the last thing you want to do is keep reloading the page each time you make CSS and JavaScript file changes. Live Reload helps out by applying your CSS and JavaScript changes without reloading the page.

When it comes to other file changes (html, image, server-side script, etc) Live Reloader automatically reloads the page.

Get it: https://chrome.google.com/webstore/detail/jnihajbhpnppcggbcgedagnkighmdlei


3. Dotjs

Dotjs is a Google Chrome extension that executes JavaScript files in ~/.js based on their filename.

Dotjs makes it super easy to spruce up your favorite pages using JavaScript.

All files in ~/.js have jQuery 1.6 loaded, regardless of whether the site you’re hacking uses jQuery. And ~/.js/default.js is loaded on every request, meaning you can stick plugins or helper functions in it.

Get it: http://defunkt.io/dotjs/


4. CoffeeConsole

A Chrome extension that lets you do CoffeeScript right from the console in Chrome’s Web Inspector.

CoffeeConsole is a Chrome extension that adds a new panel inside the Web Inspector. Type in any CoffeeScript and then hit the run button (or hit Command-Enter or Shift-Enter). The code will be compiled into JavaScript and then run in the context of the current window.

Get it: http://snook.ca/archives/browsers/coffeeconsole

5. jQuery API Browser

Quickly browse through jQuery API documentation with autocomplete search.

A simple extension for jQuery developers that allows you to quickly search through API documentation.

Displays a short method description, a list of available parameters, and provides a direct link of this method on the jQuery site. All alternate signatures for the current method are also shown.

Get it: https://chrome.google.com/webstore/detail/abefhanahjellfbchdmkjdcchkogijhk

6. Github Commits & Diffs

This Crossrider extension, developed by Dor Kalev, lets you see all the diffs for every commit on a single page.

Instead of having to spend time browsing through every commit to find out what the diffs are, you can now view them all on one page.

Get it: http://crossrider.com/install/2247-github-commits+diffs



If you know of an awesome extension that you think we should have added, let us know in the comments below.

Filed under web development browser extension javascript

1 note &

How To Create Your Own Image Sharing Extension

Image sharing is huge. It’s changing the way we communicate and engage with each other. As photo sharing sites like Pinterest, Instagram and Tumblr grow in popularity, the demand for us to find different ways to interact and share visual content is on the rise.

If you’re thinking of developing an awesome hack for sharing images then one option is to turn it into a browser extension.

I’m going to look at how to create a browser extension that will detect every image on a page and let you share them straight to your Tumblr site.

How To Detect Images
In theory an image-sharing browser extension is pretty straightforward; all you have to do is collect all the image tags on a page. Simple.

Not really. If you want to be able to collect every single image then it’s going to take more than just collecting image tags to do so. Because there are tons of images that don’t have a simple image tag, making it harder to detect them.

Finding a way to detect these images, like background images or Facebook images, that have a complex HTML is a real pain.

At Crossrider we’re always looking for ways to make browser extension development easy so we created the Images Plugin to make developing your image-sharing extension simple.

Released today, the Images Plugin uses an algorithm to detect what constitutes an image (including all the hard to detect image types) and what doesn’t (like background image repeat). While it’s deceptively easy to use it’s a very powerful and comprehensive plugin.

How To Interact With Your Collected Images
Now that your extension can detect every image on the page, you’re going to want to do something with it.

The Images Plugin lets you add an icon to every image allowing you to interact with the image. You might want it to link to a specific site or to be an element within another extension of yours. If you prefer you can add HTML text over an image instead for the same outcome.

How To Create An Extension That Shares Every Image To Tumblr
Here’s how (it only takes 3 steps):

Step 1:
To start you need to add the Images Plugin to your IDE.

Step 2:
Initialize the Images Plugin class.

Now set the iconRules parameter to include the icon HTML.

var imagesHook = appAPI.hooks.register('images', {
    iconRules:{
        html:'<a style="background:url(http://platform.tumblr.com/v1/share_1.png) top left no-repeat transparent;cursor:pointer !important;
display:inline-block;text-indent:-9999px;overflow:hidden;width:81px;height:20px;" href="javascript://" title="Share on Tumblr" target="_newTab">Share on Tumblr</a>', autoAdd:true } });


Step 3:
Listen to the iconClick event.

imagesHook.addListener('iconClick', function (data) {
    var url = 'http://www.tumblr.com/share/photo?source={url}&caption=&clickthru=';

    window.open(url.replace('{url}', encodeURIComponent(data.imgData.url)), 'tumble_share', 'width=500, height=500');
});



Done! There’s really no reason for you to be reading this sentence. You should already be in the middle of coding your own extension. Go code!

Haven’t got a Crossrider account yet? Sign up here

Filed under images sharing engagement web development social media browser extension