ChromeExtensions Message Passing

Google Chrome is an extensively used browser and is quite popular among developer too. A part of Chrome’s appeal is owed to its excellent extensions. Its not really hard to write simple extension for added convenience.

I am a Ruby on Rails developer and spend quite good amount of time using Google Chrome for development and testing Rails applications. I prefer some background music while working, it helps me cut out out the crap and concentrate better on my work.

Youtube is excellent music service for me. With youtube autoplay enabled, the game becomes even simpler.

Only problem now is, when I have to pause music I have to switch to youtube tab and then hit the pause button. And same when I want resume it.  This is a pain.

Solution:  Build a chrome extension to play/pause youtube without having to switch tabs.
All it needs is a little javascript, html and may be some css if you want things to be a little more pretty. Since we won’t do any user-interface here, we don’t need to think html/css.

How it Works ?

Extensions allow you to add functionality to Chrome without diving deeply into native code. You can create new extensions for Chrome with those core technologies that you're already familiar with from web development: HTML, CSS, and JavaScript.

We’ll do this by implementing a UI element Chrome calls  browser action, which allows us to place a clickable icon right next to Chrome’s Omnibox for easy access. Clicking that icon will play/pause the youtube video irrespective of the current active tab.

ChromeExtYTPP

Lets get started…

Every chrome extension needs to have a file named manifest.json in extension root directory. Lets create one.

manifest_version:2 We are using Chrome Extension menifest specification version 2.

name:YTPP Name for extension

version:0.1 Release version number. We need to increment this with every future release.

description:"YTPP: YouTube Play/Pause without switching tabs" Short description for out extension.

icons: {"128": "icon.png", "48": "icon_48.png", "16": "icon_16.png"} Icon files for different sizes.

author: {"name": "spidergears", "twitter_handle": "spider_gears", "github": "http://github.com/spidergears"} Author Info

browser_action: { "default_icon": "icon.png", "default_title": "YTPP"} Specifications for browser action.

"permissions": ["tabs"] List of browser permissions extension needs to be functional.

"background": {"scripts": ["ytpp_background_script.js"]} Register javascript to be run background. Will call code from this script on click of the browser action button.

"content_scripts": [{"matches": ["http://www.youtube.com/*", "https://www.youtube.com/*"], "js": ["ytpp_content_script.js"]}] Register javascript to be inject into page content. matches keys helps specify on which all websites will the script be injected.

We have manifest file ready. Lets bring in our content and background scripts.

Background Script

Background scripts are a part of background page that  runs in the extension process. Background page exists for the lifetime of the extension, and only one instance of it at a time is active. (Exception: if your extension uses incognito “split” mode, a second instance is created for incognito windows.)

In a typical extension with a background page, the UI — browser action button in our case is implemented by dumb views. When the view needs some state, it requests the state from the background page. When the background page notices a state change, the background page tells the views to update.

Now we want to play/pause youtube media when `browser action` button is clicked.

To accomplish this, we attach a click listener to our `action button` . On button click we loop through all open tabs and check if they are tabs running youtube. For all tabs running youtube, we send a message to our injected script. The inject script, on receipt of message will actually take action to play/pause youtube media.

Content Script

Content scripts are JavaScript files that run in the context of web pages. By using the standard Document Object Model (DOM), they can read details of the web pages the browser visits, or make changes to them.

Here are some examples of what content scripts can do:

  • Find unlinked URLs in web pages and convert them into hyperlinks
  • Increase the font size to make text more legible
  • Find and process microformat data in the DOM

However, content scripts have some limitations. They cannot:

These limitations aren’t as bad as they sound. Content scripts can indirectly use the chrome.* APIs, get access to extension data, and request extension actions by exchanging messages with their parent extension. Content scripts can also make cross-site XMLHttpRequests to the same sites as their parent extensions, and they can communicate with web pages using the shared DOM.

Let’s setup our content script that will be injected into the page. Our script will listen for a message from our browser action button. On message receipt it will grab the youtube play/pause button and click it to toggle media playback.

Easy!!!

Full source code is available in Github Repository.

Extension is published here.

 

Advertisements

Create a Github Repo from the Command Line

Git is a great version control system and Github is superb hosting service for git based repositories.

Github provides a nice web interface to create (blank) repositories at the start of project. But why visit github.com to  create  a blank repository, so here’s a simple bash script  to make this simple task even simpler.

Script is based on Curl and GithubApi.

 

Add this to bash_profile and reload it. Done 🙂
Use git-create to summon 146822610729350.

Be sure to configure github username and access_token in global git configure file.

Hint:

git config --global user.name <username>

git config --global user.token <access_token>

Idempotent Seeds

You Reap What You Sow rake db:seed

seeds

When working with database based applications more often than not, some seed data needs to be created. For example, I’ve used seed data to create an admin_user and a few dummy_users so the site can be used upon a fresh install. Some other common cases include things like, list of names of countries/states, list of user roles, list of permissions etc.
This post is about some ideas to manage seed data in a Ruby on Rails project.

In a Rails application seeds can be put at two places

  • db/seeds.rb [Standard practice]
  • db/migrate/232422_some_migration.rb [*its a possibility]

db/seeds.rb is the obvious place for seeds. Don’t mess around with it unless absolutely necessary.

Some points to keep in mind when sowing seeds:

  • Handling large seed data
    • Split seed files into multiple files clearly indicating your objects and business logic. A sample might look like
              |-app
                |-db
                  -seeds.rb
                  |-seeds
                    -user.rb
                    -roles.rb
                    -plans.rb
    •  Inside seeds.rb require sub seed-files as
      require 'seeds/user.rb'
      require 'seeds/roles.rb'
      require 'seeds/plans.rb'
    • If number of seeds for a business object is large, consider loading it from yaml files. Keeping business logic separate from data is a good practice.
  • Idempotent seeds
    • Idempotent,  a mathematical term that means that something remains the same when some operation is applied to it, using itself as input.
    • For example, multiplication by identity element  5 X 1 = 5.
    • Having idempotent seed files means, they can be run multiple times without causing any issue.
    • Instead of creating or updating objects blindly, it first tries to find the object and check its state.