In this post I am going to discuss how I went about making the League of Legends extension, and what goes into making a Chrome extension in general. For an introductory tutorial on making a Chrome extension, click here.
Skills Used: For the creation of the extension, I used Javascript, and HTML. The bulk of the extension is Javascript.For the Javascript, I use Jquery, because it makes development a lot quicker and easier, and allowed me to add quite robust features without doing a lot of work, debugging, or coding.
Basics of a Chrome Extension: Everyone Google Chrome extension is different, but what they all have in common is one file required by Google Chrome called manifest.json. JSON stands for Javascript Object Notation, and is basically the standardized notation that Javascript uses when creating object.
The next file(s) common to most extensions are content scripts. These are Javascript files that run in the background of the webpage that your extension works on. For the League of Legends Forum Extension, there are a few content scripts that run in the background. The main script loads all the features, while the others are support scripts. For example, There are two files that contain the Javascript array that holds all the item and champion names with links to their respective wiki pages. There is also the Jquery library file, and a file that has the code that creates the quick navigation bar.
Icons… Icons Everywhere: Most Chrome extensions have an Icon associated with them, and mine is no different. My extension actually has two icon files. One icon is the icon for the extension that you can see on its Chrome Store page. The second icon is the icon that you can see on your chrome extension page (which can be reached by clicking on the wrench in the upper right corner of your browser, and going to Tools > Extensions/
Feature Explanation: In this section, I am going to go into detail about how I went about developing the various features of the extension. This section is going to be heavy in programming terminology, so if you don’t know much about Computer Science or Programming, feel free to skip this section, as it probably won’t make much sense.
- Quick Navigation Bar:
- This simply consists of a string variable that contains the HTML that makes up the quick navigation bar. I use Jquery to add this actual object to the page body. I set it up so that it starts with an opacity of .2 (or 20%). I created a hover event that, when fired, increases the opacity to 100%. Obviously, the quick navigation bar only appears if the option is enabled. It is enabled by default.
- Image Expansion:
- This one took a bit of doing. I start off by using Jquery to select all the links that surround the image attachment thumbnails, and disabling them. I them select all the images, and give them an OnClick event. When this event fires, I change the source of the image to the actual big version of the image. I do this by simply taking the source of the thumbnail, and removing the part of the source that says “thumb=1”. The way that attachments in the forums work is they are served to the user by a PHP page that sends the MIME type as an image. After I change the source, I set the display style to none, which will hide the image. I do this so that I can check the width of the image first, and if it isn’t too big, I fade it in. If it is too big, then I create a new div with the image inside, and add it to the page body via Jquery. I set the position as absolute, and use the mouse’s X and Y coordinates (retrieved via Jquery) as the left and top position respectively.
- Red Post Preview
- This is probably my favorite feature. When the page loads, I select all the red post icons, and get the URL that they each link too. I then use an AJAX (If you don’t know what this is, read about it here) request to get the content of the page, and use Jquery to parse the page content and get just the content of the red post. Using this content, I create a hidden div which I append to the bottom of the page. I then add a hover event to the red post icons that, when fired, creates a new div positioned at the mouse X and Y position and fades it in. When your mouse leaves the red post icon and div fades out. However, it won’t fade out if your mouse stays hovered over the actual div with the red post content. I did this so that longer posts can be viewed if you need to scroll your window down.
- Youtube Link Conversion:
- This was actually the second feature I implemented. I used Jquery to select all the links to a Youtube video. I did this by selecting all links with the string “youtube.com/watch” anywhere in the href attribute. I then used the href attribute to construct an embed tag that pointed to the specific video. Using Jquery I also selected all the text inside the post content div which contained the string “youtube.com/watch” and used that text to create an embed tag much in the same way I used it with links. Theoretically, because I do this, someone could write the text “youtube.com/watch” with some nonsense after it, and it will attempt to embed a video that doesn’t exist.
- Champion and Item name Conversion:
- This was the first feature I implemented in the extension, and the first version (1.0.0) basically consisted of this functionality. I used Jquery (surprise, surprise) to select all the div tags with an id attribute that starts with the string “post_message”. I then took that text, and did a regular expression replace that with a pattern that matches a specific item or champion name (as long as its not part of a link) and replaces it with a link to that specific champion or items wiki page. I keep an array with the item and champion names and links in two separate files. The array uses the champion/item names as keys, and the links to the wiki pages as values. I generate these arrays with a PHP script that spiders the League of Legends webpage for all the champion and item names. The unfortunate thing about this process is Riot doesn’t update their information database very often, so when new champions or items are released, sometimes I have to enter the key/value pairs by hand. For certain champions/items with single quotes in their names (like Cho’Gath or Kog’Maw) I have multiple entries in the array to match not only the champion with a quote is his name, but his name without a quote, or with a space instead of a quote. For example, Cho’Gath has three entries. Cho’Gath, ChoGath, and Cho Gath. The pattern matching is also case insensitive, so CHO’gath would also be matched, as well as many others.
- Left/Right arrow Keybindings:
- This feature was suggested by ItzWartzy. I simply binded the left and right key press event to the body tag using Jquery. When this event fires, I select the Next/Previous link’s href attribute (by selecting all links with a rel attribute equal to next/previous) using Jquery, and change the window.location variable to this href attribute. I make sure to check that the link actually exists (IE your on the last page for left arrow, or first page for right arrow), and if it doesn’t, nothing happens.
- Thread Number of Pages:
- This feature was quite simple. I simply select all the links with the anchor text containing “Last Page” using Jquery, and parse the page number out of the href attribute. I then append text with “X pages” (X being the number of the last page) after the selected link.
- Options Page:
- This is an ever changing feature, since when I add new features, I must add them to the options page, and make sure the options work. The problem that I ran into with this feature was that content scripts in a Chrome extension run independent of the rest of the extension. Its basically like the content script is part of the actual web page, rather than the extension. Because of this, content scripts can’t access any other part of the extension, unless you send a request from the content script to the extension. You can read more about this process (known as message passing) here. The information I needed to retrieve was the localStorage array, which is a cookie-like array that browsers can use to store information about a website locally on the clients computer.
- On the options page, whenever an option is selected/deselected, the entry is entered/altered in the localStorage array. When the options page is first loaded, I check/uncheck certain selections based on what is in the localStorage array. If the localStorage array is empty (IE when first installing the extension), all the options are checked by default, and those values are entered into the array. The structure of the array is the id attribute of each check box is the array keys, and the values are true/false if the option is checked/unchecked. If a user never opens the options page, the localStorage array will be empty. Because of this, when I check the options when executing the code for the various features, the if statement consists of two boolean statements OR’ed together. The feature will be loaded if the various option are true (IE they are checked) or if the localStorage array that was retrieved using message passing (link above) is undefined. I do this because by default, all options are enabled. As I continue to add features certain features may be disabled by default, so obviously I would have to change the conditional.
- Miscellaneous Information:
- I use the latest version of Jquery, which is version 1.6.1, minified.
- The Message passing request is a one time request (sendRequest method of the chrome.extension object) to the background.html page. This page consists of a single javascript tag, where I add a listener to the onRequest port. In this listener, I send a response consisting of the localStorage array.
- My version system is arbitrary and doesn’t really mean anything. However, I use single digits between each period. IE there will never be a version 1.3.11
- The features are all executed when the document.ready() event is fired.
- All the features are executed on a single javascript page. Board and Thread features are seperated by an if statement that checks the URL of the current page your on.
If anyone has any questions or comments on how I am doing things, Please don’t hesistate to leave a comment, or email me at Mikesta707@yahoo.com. Thanks to everyone for your support. Hope you enjoy the extension.