<?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>Billd Labs</title>
	<atom:link href="http://www.billdlabs.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.billdlabs.com</link>
	<description>For Fun and Profit</description>
	<lastBuildDate>Thu, 18 Apr 2013 15:12:26 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>BitNotifier 1.2.01 Is Out</title>
		<link>http://www.billdlabs.com/?p=94</link>
		<comments>http://www.billdlabs.com/?p=94#comments</comments>
		<pubDate>Thu, 18 Apr 2013 15:12:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[BitNotifier]]></category>
		<category><![CDATA[Windows Applications]]></category>

		<guid isPermaLink="false">http://www.billdlabs.com/?p=94</guid>
		<description><![CDATA[Last week a change was made to the API I use to gather data from MtGox. This made BitNotifier think MtGox stopped responding, even though it was. It took a little bit to pinpoint the problem, but I sorted it out. You can download the newest version here: http://billdlabs.com/BitNotifier/1-20-01/setup.exe.]]></description>
				<content:encoded><![CDATA[<p>Last week a change was made to the API I use to gather data from MtGox. This made BitNotifier think MtGox stopped responding, even though it was. It took a little bit to pinpoint the problem, but I sorted it out. You can download the newest version here: <a title="http://billdlabs.com/BitNotifier/1-20-01/setup.exe" href="http://billdlabs.com/BitNotifier/1-20-01/setup.exe">http://billdlabs.com/BitNotifier/1-20-01/setup.exe</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.billdlabs.com/?feed=rss2&#038;p=94</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BitNotifier is now Open Source</title>
		<link>http://www.billdlabs.com/?p=91</link>
		<comments>http://www.billdlabs.com/?p=91#comments</comments>
		<pubDate>Thu, 21 Mar 2013 16:19:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[BitNotifier]]></category>
		<category><![CDATA[Windows Applications]]></category>

		<guid isPermaLink="false">http://www.billdlabs.com/?p=91</guid>
		<description><![CDATA[BitNotifier will continue production as an open source application. You can download it from https://github.com/Billdlabs/BitNotifier. Enjoy!]]></description>
				<content:encoded><![CDATA[<p>BitNotifier will continue production as an open source application. You can download it from <a href="https://github.com/Billdlabs/BitNotifier">https://github.com/Billdlabs/BitNotifier</a>. Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.billdlabs.com/?feed=rss2&#038;p=91</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BitNotifier 1.2 is out</title>
		<link>http://www.billdlabs.com/?p=71</link>
		<comments>http://www.billdlabs.com/?p=71#comments</comments>
		<pubDate>Tue, 05 Mar 2013 10:24:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[BitNotifier]]></category>
		<category><![CDATA[Windows Applications]]></category>

		<guid isPermaLink="false">http://www.billdlabs.com/?p=71</guid>
		<description><![CDATA[I&#8217;ve taken the feedback given so far and made some tweaks to the software. Change log Spacing on G19 should be fixed. I don&#8217;t have a G19, so some guess work is going into this. Centered the text on the UI. Added volume to the UI. Moved website and donation functionality to the menu bar. [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve taken the feedback given so far and made some tweaks to the software.</p>
<p><strong>Change log</strong></p>
<ul>
<li><span style="line-height: 12.997159004211426px;">Spacing on G19 should be fixed. I don&#8217;t have a G19, so some guess work is going into this.</span></li>
<li>Centered the text on the UI.</li>
<li>Added volume to the UI.</li>
<li>Moved website and donation functionality to the menu bar.</li>
<li>Added tabs to the UI.</li>
<li>Added a calculator to the UI.</li>
</ul>
<p><a style="font-size: 13px; line-height: 19px;" href="http://www.billdlabs.com/wp-content/uploads/2013/03/calc.jpg"><img class="size-medium wp-image-76 aligncenter" alt="calc" src="http://www.billdlabs.com/wp-content/uploads/2013/03/calc-208x300.jpg" width="208" height="300" /></a></p>
<p><span style="font-size: 13px; line-height: 19px;">You can download the latest version <a title="BitNotifier 1.2" href="http://billdlabs.com/BitNotifier/1-20-0/setup.exe" target="_blank">here</a>.</span></p>
<p>If you installed a previous version I&#8217;m afraid you&#8217;ll need to manually uninstall it before you can install this one. I&#8217;m looking into why that&#8217;s happening and hope to address it in a future release. My plans for the next version are going to be &#8220;behind the scenes&#8221; improvements which should lead to this project going open source . After that, I&#8217;ve got a list of features I&#8217;d like to implement including deeper MtGox support, personal wealth tracking, and maybe integration with some of the more popular software miners out there.</p>
<p>Do you want to see a feature that isn&#8217;t on my radar yet? Let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.billdlabs.com/?feed=rss2&#038;p=71</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Introducing BitNotifier</title>
		<link>http://www.billdlabs.com/?p=59</link>
		<comments>http://www.billdlabs.com/?p=59#comments</comments>
		<pubDate>Sat, 02 Mar 2013 00:37:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[BitNotifier]]></category>
		<category><![CDATA[Windows Applications]]></category>

		<guid isPermaLink="false">http://www.billdlabs.com/?p=59</guid>
		<description><![CDATA[I love bitcoins. I think they&#8217;re the greatest thing since e-mail. I&#8217;ve been kind of hung up on trading over at Mt Gox. However, I hated having to keep an eye on my web browser all of the time. So I decided to write an application that&#8217;d show me the last trade price in the [...]]]></description>
				<content:encoded><![CDATA[<p>I love <a title="We Use Coins" href="http://www.weusecoins.com/" target="_blank">bitcoins</a>. I think they&#8217;re the greatest thing since e-mail. I&#8217;ve been kind of hung up on trading over at <a title="Mt Gox" href="http://www.mtgox.com" target="_blank">Mt Gox</a>. However, I hated having to keep an eye on my web browser all of the time. So I decided to write an application that&#8217;d show me the last trade price in the system tray.</p>
<p><img class="size-full wp-image-60 aligncenter" alt="notification icon" src="http://www.billdlabs.com/wp-content/uploads/2013/03/notificationicon.jpg" width="138" height="76" /></p>
<p>Mission accomplished. Then I wanted some more information, like the high, low, average, current asking price and current buying price. So I made a window to show it to me.</p>
<p><a href="http://www.billdlabs.com/wp-content/uploads/2013/03/mainscreen.jpg"><img class="size-medium wp-image-61 aligncenter" alt="main screen" src="http://www.billdlabs.com/wp-content/uploads/2013/03/mainscreen-258x300.jpg" width="258" height="300" /></a></p>
<p>Hey, neat. But what about when I&#8217;m playing video games and can&#8217;t see my desktop at all? Well, I have my Logitech G510 (should also work with G15, and G19) for that. If you don&#8217;t have one of these amazing keyboards, no worries &#8211; the other features still work!</p>
<p><a href="http://www.billdlabs.com/wp-content/uploads/2013/03/lcdDisplay.jpg"><img class="size-medium wp-image-62 aligncenter" alt="LCD Display" src="http://www.billdlabs.com/wp-content/uploads/2013/03/lcdDisplay-300x225.jpg" width="300" height="225" /></a></p>
<p><span style="font-size: 13px; line-height: 19px;">And hey, that&#8217;s version 1! A desktop bitcoin market ticker with Logitech</span><span style="font-size: 13px; line-height: 19px;"> keyboard applet support. <a title="Download Now" href="http://www.billdlabs.com/BitNotifier/1-0-1/setup.exe" target="_blank">Here&#8217;s a ~2mb download</a> to install it on your pc. I have some plans for future versions, but I was anxious to share what I&#8217;ve got so far. Please note this is a really early build. Let me know if you find any bugs.</span></p>
<p>Update: I added a feature. The icons, text, and led updates when MtGox does not respond for some reason.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.billdlabs.com/?feed=rss2&#038;p=59</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using DotNetOpenAuth to Authenticate Against StackOverflow in an MVC 4 Application</title>
		<link>http://www.billdlabs.com/?p=45</link>
		<comments>http://www.billdlabs.com/?p=45#comments</comments>
		<pubDate>Thu, 10 Jan 2013 02:43:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Web Sites]]></category>

		<guid isPermaLink="false">http://www.billdlabs.com/?p=45</guid>
		<description><![CDATA[Today I wanted to learn how to implement oAuth in as small a foot print as possible. I&#8217;ve written my own custom oAuth client before, but it was very bulky and not very reusable. Since DotNetOAuth ships with all .NET 4.0 MVC Web Applications (and I assume WebForms as well), I thought I&#8217;d look into [...]]]></description>
				<content:encoded><![CDATA[<p>Today I wanted to learn how to implement oAuth in as small a foot print as possible. I&#8217;ve written my own custom oAuth client before, but it was very bulky and not very reusable. Since DotNetOAuth ships with all .NET 4.0 MVC Web Applications (and I assume WebForms as well), I thought I&#8217;d look into writing against it. I wasn&#8217;t able to find much in the way of existing documentation or tutorials, so I&#8217;m posting my results for you. My examples are written for StackOverflow, but the same idea should apply to any OAuth provider.</p>
<p>We&#8217;re going to need three classes. They&#8217;ll be tightly coupled, so feel free to put them in a single file (as I did). Two of these classes are data contracts, and the third moves your data around. Let&#8217;s start with the data contracts.</p>
<p>They should simply mirror the json/xml result you expect to receive. StackOverflow throws a lot of data back on a simple user lookup request. Here&#8217;s what their JSON looks like:</p>
<pre>{
  "items": [
    {
      "user_id": 1284102,
      "user_type": "registered",
      "creation_date": 1332351699,
      "display_name": "Billdr",
      "profile_image": "http://www.gravatar.com/avatar/30a850dc91432d86e940e4788a3f1c42?d=identicon&#038;r=PG",
      "reputation": 536,
      "reputation_change_day": 0,
      "reputation_change_week": 10,
      "reputation_change_month": 10,
      "reputation_change_quarter": 10,
      "reputation_change_year": 10,
      "age": 30,
      "last_access_date": 1357764683,
      "last_modified_date": 1355755828,
      "is_employee": false,
      "link": "http://stackoverflow.com/users/1284102/billdr",
      "website_url": "http://www.billdlabs.com/",
      "location": "Minneapolis, MN",
      "account_id": 1342727,
      "badge_counts": {
        "gold": 0,
        "silver": 1,
        "bronze": 16
      },
      "accept_rate": 92
    }
  ],
  "quota_remaining": 9993,
  "quota_max": 10000,
  "has_more": false
}</pre>
<p>So how do we model all of that as C# classes? Well, you&#8217;ll notice the data we actually want is wrapped up in an array called &#8220;items.&#8221; So, we need to create a class to wrap the data we actually want. For completeness, I also included the quota information at the end. </p>
<pre>    [DataContract]
    class StackOverflowJsonReturns
    {
        [DataMember(Name = "items")]
        public IEnumerable&lt;StackOverflowClientData&gt; Users { get; set; }

        [DataMember(Name = "quota_remaining")]
        public int QuotaRemaining { get; set; }

        [DataMember(Name = "quota_max")]
        public int QuotaMax { get; set; }

        [DataMember(Name = "has_more")]
        public bool HasMore { get; set; }
    }
</pre>
<p>You&#8217;ll see I wrapped the actual data in it&#8217;s own class, &#8220;StackOverflowClientData.&#8221; Here&#8217;s what that looks like.</p>
<pre>
    [DataContract]
    class StackOverflowClientData
    {
        [DataMember(Name = "user_id")]
        public int Id { get; set; }

        [DataMember(Name = "user_type")]
        public string SOUserType { get; set; }

        [DataMember(Name = "creation_date")]
        public int SOJoinDate { get; set; }

        [DataMember(Name = "display_name")]
        public string DisplayName { get; set; }

        [DataMember(Name = "profile_image")]
        public Uri ProfileImage { get; set; }

        [DataMember(Name = "reputation")]
        public int Reputation { get; set; }

        [DataMember(Name = "reputation_change_day")]
        public int ReputationChangeDay { get; set; }
        
        [DataMember(Name = "reptutation_change_week")]
        public int ReputationChangeWeek { get; set; }

        [DataMember(Name="reputation_change_month")]
        public int ReputationChangeMonth { get; set; }

        [DataMember(Name="reputation_change_quarter")]
        public int ReputationChangeQuarter { get; set; }

        [DataMember(Name = "reputation_change_year")]
        public int ReputationChangeYear { get; set; }

        [DataMember(Name = "age")]
        public int Age { get; set; }

        [DataMember(Name = "last_access_date")]
        public int LastAccessDate { get; set; }

        [DataMember(Name = "last_modified_date")]
        public int LastModifiedDate { get; set; }

        [DataMember(Name = "is_employee")]
        public bool SOEmployee { get; set; }

        [DataMember(Name = "link")]
        public Uri SOPage { get; set; }

        [DataMember(Name = "website_url")]
        public Uri PersonalPage { get; set; }

        [DataMember(Name = "location")]
        public string Location { get; set; }

        [DataMember(Name = "account_id")]
        public int SOAccountId { get; set; }

        [DataMember(Name = "badge_counts")]
        public IEnumerable&lt;KeyValuePair&lt;string,int&gt;&gt; BadgeCount { get; set; }

        [DataMember(Name="accept_rate")]
        public int AcceptRate { get; set; }
    }</pre>
<p>This class made me want to hire someone to do data entry. 99% of the reason you&#8217;re reading this code is because I don&#8217;t want you to suffer like I suffered, creating that class. Now that the data management is out of the way, here&#8217;s the code that does the work.</p>
<pre>    public class SEoAuthClient : OAuth2Client
    {
        #region Constants and Fields
        private const string AuthorizationEndpoint = "https://stackexchange.com/oauth";
        private const string TokenEndpoint = "https://stackexchange.com/oauth/access_token";
        private readonly string appId;
        private readonly string appSecret;
        private readonly string key;
        #endregion

        #region Constructors and Destructors

        /// The public constructor for a new instance of theSEoAuthClient class.
        public SEoAuthClient(string appId, string appSecret, string key)
            : this("Stack Overflow", appId, appSecret, key)
        {
        }

        /// Initializes a new instance of the SEoAuthClient class.
        protected SEoAuthClient(string providerName, string appId, string appSecret, string key)
            : base(providerName)
        {
            if (!string.IsNullOrEmpty(appId))
            {
                this.appId = appId;
            }
            else
            {
                throw new Exception("Missing required data in appId when calling SEoAuth.");
            }
            if (!string.IsNullOrEmpty(appSecret))
            {
                this.appSecret = appSecret;
            }
            else
            {
                throw new Exception("Missing required data in appSecret when calling SEoAuth.");
            }
            if (!string.IsNullOrEmpty(key))
            {
                this.key = key;
            }
            else
            {
                throw new Exception("Missing required data in key when calling SEoAuth.");
            }
        }
        #endregion

        /// Gets the id for this client as it is registered with SE.
        protected string AppId
        {
            get { return this.appId; }
        }

        #region Methods
        /// Builds the URL the user will be directed to, with queries.
        protected override Uri GetServiceLoginUrl(Uri returnUrl)
        {
            var builder = new UriBuilder(AuthorizationEndpoint);
            builder.Query = "client_id=" + this.appId + "&#038;redirect_uri=" + HttpUtility.UrlEncode(returnUrl.AbsoluteUri);
            return builder.Uri;
        }

        /// Sends a request with the access token to fetch the user's data. 
        /// This is actually the last method to be called in the flow.
        protected override IDictionary&lt;string, string&gt; GetUserData(string accessToken)
        {
            StackOverflowClientData graph;
            //SE returns the user data as a JSON formatted string, compressed with gzip. For my sanity's sake we're going after it with a WebClient instead of a WebRequest.
            using (var client = new WebClient())
            { 
                //SE requests this be set, even if it 'fails back' to gzip anyway. We're nice folks.
                client.Headers[HttpRequestHeader.AcceptEncoding] = "gzip";   
                client.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8;";
                var data =
                    client.DownloadData("https://api.stackexchange.com/2.1/me?site=stackoverflow&#038;key=" +
                                        HttpUtility.UrlEncode(key) + "&#038;access_token=" +
                                        HttpUtility.UrlEncode(accessToken));

                string jsonString = string.Empty;

                //this block decompresses the result and turns it into a string. 
                using (var gzipStream = new GZipStream(new MemoryStream(data), CompressionMode.Decompress))
                {
                    const int size = 4096;
                    var buffer = new byte[size];
                    using (var memory = new MemoryStream())
                    {
                        int count = 0;
                        do
                        {
                            count = gzipStream.Read(buffer, 0, size);
                            if (count &gt; 0)
                            {
                                memory.Write(buffer, 0, count);
                            }
                        } while (count &gt; 0);
                        //failing to return the position to 0 generates an obnoxious error.
                        memory.Position = 0;
                        //DotNetOpenAuth uses DataContractJsonSerializer, so that's what we're doing
                        var des = new DataContractJsonSerializer(typeof(StackOverflowJsonReturns));
                        var allData = (StackOverflowJsonReturns) des.ReadObject(memory);
                        graph = allData.Users.First();
                    }
                }
            }
            //Now we take all of our carefully formatted data and toss it into a string, string dictionary.
            var userData = new Dictionary&lt;string, string&gt;();
            userData.Add("id", graph.Id.ToString());
            userData.Add("username", graph.DisplayName);
            userData.Add("name", graph.DisplayName);
            userData.Add("link", graph.SOPage.ToString());
            userData.Add("user_type", graph.SOUserType);
            userData.Add("creation_date", graph.SOJoinDate.ToString());
            userData.Add("profile_image", graph.ProfileImage.ToString());
            userData.Add("reputation", graph.Reputation.ToString());
            userData.Add("reputation_change_day", graph.ReputationChangeDay.ToString());
            userData.Add("reputation_change_week", graph.ReputationChangeWeek.ToString());
            userData.Add("reputation_change_month", graph.ReputationChangeMonth.ToString());
            userData.Add("reputation_change_quarter", graph.ReputationChangeQuarter.ToString());
            userData.Add("reputation_change_year", graph.ReputationChangeYear.ToString());
            userData.Add("age", graph.Age.ToString());
            userData.Add("last_access_date", graph.LastAccessDate.ToString());
            userData.Add("last_modified_date", graph.LastModifiedDate.ToString());
            userData.Add("website_url", graph.PersonalPage.ToString());
            userData.Add("location", graph.Location);
            userData.Add("account_id", graph.SOAccountId.ToString());
            foreach (KeyValuePair&lt;string, int&gt; kvp in graph.BadgeCount)
            {
                userData.Add(kvp.Key, kvp.Value.ToString());
            }
            userData.Add("accept_rate", graph.AcceptRate.ToString());

            return userData;
        }

        /// Trades the authorization code in for an access token.
        protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
        {
            var entity = "client_id=" + this.appId + "&#038;client_secret=" + this.appSecret + "&#038;code=" + authorizationCode +
            "&#038;redirect_uri=" + HttpUtility.UrlEncode(returnUrl.AbsoluteUri);

            var tokenRequest = WebRequest.Create(TokenEndpoint);
            tokenRequest.ContentType = "application/x-www-form-urlencoded";
            tokenRequest.ContentLength = entity.Length;
            tokenRequest.Method = "POST";

            using (Stream requestStream = tokenRequest.GetRequestStream())
            {
                var writer = new StreamWriter(requestStream);
                writer.Write(entity);
                writer.Flush();
            }

            HttpWebResponse tokenResponse = (HttpWebResponse) tokenRequest.GetResponse();
            if (tokenResponse.StatusCode == HttpStatusCode.OK)
            {
                using (Stream responseStream = tokenResponse.GetResponseStream())
                {
                    //SE gives us the response as a string. Not an argument appended to the callback but a string in the body of a page.
                    // It looks like this: access_token=fdagfdsf4&#038;expires=8600
                    var response = tokenResponse.GetResponseStream();
                    StreamReader reader = new StreamReader(responseStream);
                    var responseString = reader.ReadToEnd();
                    var tokenSection = responseString.Split('&#038;')[0];
                    return tokenSection.Split('=')[1];
                }
            }
            return null;
        }
        #endregion
    }</pre>
<p>One last thing! In your <code>/App_Start/AuthConfig.cs</code> file, you will need to add this line somewhere in the <code>RegisterAuth()</code> method: <code>OAuthWebSecurity.RegisterClient(new SeoAuthClient("YourAppId", "YourAppSecret", "YourKey"), "Stack Overflow", null);</code. The "Stack Overflow" is the text that will appear in the button on the Sign In page.</p>
<p>If anything needs clarification, please contact me or leave a comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.billdlabs.com/?feed=rss2&#038;p=45</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to execute assembly written for x86 on Windows 7 x64</title>
		<link>http://www.billdlabs.com/?p=40</link>
		<comments>http://www.billdlabs.com/?p=40#comments</comments>
		<pubDate>Tue, 06 Nov 2012 20:16:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.billdlabs.com/?p=40</guid>
		<description><![CDATA[I&#8217;m playing around in Assembly. All the tutorials out there seem to be for x86 machines. I&#8217;m on an Intel 64-bit processor running Windows 7. Nothing would run even though x64 is backwards compatible with x86. I spent all day trying to figure this out. To run assembly code written for x86 you must put [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m playing around in Assembly. All the tutorials out there seem to be for x86 machines. I&#8217;m on an Intel 64-bit processor running Windows 7. Nothing would run even though x64 is backwards compatible with x86. I spent all day trying to figure this out. To run assembly code written for x86 you must put it in the /Program Files (x86)/ folder. Hopefully you will see this and save yourself some grey hair/premature balding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.billdlabs.com/?feed=rss2&#038;p=40</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Chrome Extension: Crawling a page for specific tags and selectors</title>
		<link>http://www.billdlabs.com/?p=17</link>
		<comments>http://www.billdlabs.com/?p=17#comments</comments>
		<pubDate>Mon, 24 Sep 2012 22:42:37 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.billdlabs.com/?p=17</guid>
		<description><![CDATA[I&#8217;m about to talk about code I wrote on the job for someone else. To protect their rights to the code, this post will go through the general information needed to scrape a page with generic samples. At the end of the post you&#8217;ll have a working Chrome Extension. This was my first Chrome Extension, [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m about to talk about code I wrote on the job for someone else. To protect their rights to the code, this post will go through the general information needed to scrape a page with generic samples. At the end of the post you&#8217;ll have a working Chrome Extension. This was my first Chrome Extension, and I taught myself how to do it in a few hours. It may not adhere to best practices in all instances. If you&#8217;re making something to sell, I recommend you do further research.</p>
<p><strong>Problem: </strong>I needed to take all CSS selectors from a page I had written and store it into a file to hand off to designers. There are several pages, and each page had hundreds of tags, classes, and IDs so doing it by hand would take an obnoxious amount of time.</p>
<p><strong>Solution: </strong>For this project there are five standard files of the Chrome extension that we need to build. First let&#8217;s take a look at manifest.json, which handles permissions.</p>
<p>manifest.json</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;TagRipper&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;version&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;1.0&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;manifest_version&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;description&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Looks over a page for valid CSS selectors.&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;browser_action&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;default_icon&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;icon.png&quot;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;default_popup&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;popup.html&quot;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;content_scripts&quot;</span><span style="color: #339933;">:</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;matches&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;http://*/&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;https://*/*&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;js&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;content.js&quot;</span><span style="color: #009900;">&#93;</span>
     <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;permissions&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;tabs&quot;</span><span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Let&#8217;s take this line-by-line. The first thing you&#8217;ll notice if you&#8217;re new to JSON is the entire thing is enclosed in brackets. It may look weird, but that is how it&#8217;s supposed to be. For futher reading you can check some examples of JSON compared to XML <a title="JSON Examples" href="http://json.org/example.html" target="_blank">here</a>. Some of the tags are pretty self-explanatory, such as name (the extension&#8217;s name), version (the extension&#8217;s version), and description (a description of what the extension does).</p>
<p>At the time of this writing &#8220;manifest_version&#8221; should always be set to 2. Note that&#8217;s an integer 2, not a string &#8220;2.&#8221; You can find the current manifest version (and some details about what the manifest offers) <a title="Chrome Manifest Version" href="http://developer.chrome.com/extensions/manifestVersion.html" target="_blank">here</a>.</p>
<p>The &#8220;browser_action&#8221; adds elements to the browser itself, next to the configuration wrench. &#8220;Default_icon&#8221; is the image that is displayed, and &#8220;default_popup&#8221; is the &#8220;balloon&#8221; that will come out of the icon when clicked. We&#8217;ll talk about these actual files in a moment. The icon.png I used was the one from Chrome&#8217;s &#8220;Hello World&#8221; tutorial. You can view that tutorial <a title="Chrome Hello World" href="http://developer.chrome.com/extensions/getstarted.html" target="_blank">here</a> if you haven&#8217;t been there already.</p>
<p>The &#8220;content_scripts&#8221; tells Chrome to run something in the background. The &#8220;matches&#8221; tag tells Chrome when to do it. In this example I set wildcard strings so that the script runs on all http and https connections. If you only want your extension to work for certain sites (for reskinning extensions or to provide additional functionality to a site) you would specify it there. Remeber, &#8220;*&#8221; indicates a wildcard. If you wanted to make something like the <a title="Reddit Enhancement Suite" href="http://redditenhancementsuite.com/" target="_blank">Reddit Enhancement Suite</a> the line would look like this: &#8220;matches&#8221;: ["http://www.reddit.com/*","http://reddit.com/*"]. The &#8220;js&#8221; tells Chrome we want to run javascript. We could put a script in there directly, but for readability&#8217;s sake I&#8217;ve specified a file.</p>
<p>The last line here is the &#8220;permissions&#8221; line. This application needs to see what the user is looking at in their browser, so we need the &#8220;tabs&#8221; permission. <a title="Chrome Manifest Permissions" href="http://developer.chrome.com/extensions/manifest.html#permissions" target="_blank">Here</a> is a list of permissions and a general description of what they give you access to.</p>
<p>popup.html</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="html" style="font-family:monospace;">&lt;!doctype html&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;CSSScraper&lt;/title&gt;
            &lt;style&gt;
                body
                {
                    min-width:357px;
                    overflow-x:hidden;
                }
            &lt;/style&gt;
            &lt;!-- JavaScript and HTML must be in separate files for security. --&gt;
            &lt;script src=&quot;popup.js&quot;&gt;&lt;/script&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;p id=&quot;results&quot;&gt;&lt;/p&gt;
    &lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<p>This file is very straight forward, but there are three quick points of interest: 1) I did not put the javascript here. Chrome doesn&#8217;t like it if you try. Put it in an external javascript document and move on. 2) I created an empty paragraph section in my document. This is going to be targeted by popup.js later. 3) The css styling here is what pops out when the icon is pressed. It can do anything an html/css webpage can, so go nuts with it.</p>
<p>The last two files are Javascript, so I will explain them with inline comments.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">chrome.<span style="color: #660066;">extension</span>.<span style="color: #660066;">onMessage</span>.<span style="color: #660066;">addListener</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>request<span style="color: #339933;">,</span> sender<span style="color: #339933;">,</span> sendResponse<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">//request has two properties that we're working about, Greeting and Farewell. Both variables are strings. The greeting can be anything, as long as the receiving file and sending file agree on what it is.</span>
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>request.<span style="color: #660066;">greeting</span><span style="color: #339933;">==</span><span style="color: #3366CC;">&quot;gimmieyodatas&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">//declare an array of all known html elements. I got this list from a random website. It may not be complete, but it covers everything I used.</span>
	<span style="color: #000066; font-weight: bold;">var</span> elements <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> <span style="">Array</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;a&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;abbr&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;acronym&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;address&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;applet&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;area&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;article&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;aside&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;audio&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;b&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;base&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;basefont&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;bdi&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;bdo&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;big&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;blockquote&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;body&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;br&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;button&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;canvas&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;caption&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;center&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;cite&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;code&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;col&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;colgroup&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;command&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;datalist&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;dd&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;del&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;details&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;dfn&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;dir&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;div&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;dl&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;dt&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;em&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;embed&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;fieldset&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;figcaption&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;figure&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;font&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;footer&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;form&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;frame&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;frameset&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;h1&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;h2&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;h3&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;h4&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;h5&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;h6&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;head&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;header&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;hgroup&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;hr&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;i&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;iframe&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;img&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;input&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;ins&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;keygen&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;kbd&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;label&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;legend&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;li&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;link&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;map&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;mark&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;menu&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;meta&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;meter&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;nav&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;noframes&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;noscript&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;object&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;ol&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;optgroup&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;option&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;output&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;p&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;param&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;pre&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;progress&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;q&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;rp&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;rt&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;ruby&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;s&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;samp&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;section&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;select&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;small&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;source&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;span&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;strike&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;strong&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;style&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;sub&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;summary&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;sup&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;table&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;tbody&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;td&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;textarea&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;tfoot&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;th&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;thead&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;time&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;title&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;tr&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;track&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;tt&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;u&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;var&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;video&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;wbr&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #006600; font-style: italic;">//declare an array for found elements</span>
	<span style="color: #000066; font-weight: bold;">var</span> foundElements <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> <span style="">Array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #006600; font-style: italic;">//declare an array for found ids</span>
	<span style="color: #000066; font-weight: bold;">var</span> foundIds <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> <span style="">Array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #006600; font-style: italic;">//and we're going to output everthing in a giantic string.</span>
	<span style="color: #000066; font-weight: bold;">var</span> output <span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;/*Page: &quot;</span> <span style="color: #339933;">+</span> document.<span style="color: #660066;">URL</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;*/&lt;br /&gt;&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #006600; font-style: italic;">//this counter is used to hold positions in the element array.</span>
	<span style="color: #000066; font-weight: bold;">var</span> elementCounter <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
	<span style="color: #006600; font-style: italic;">//this counter is used to hold positions in the foundIds array</span>
	<span style="color: #000066; font-weight: bold;">var</span> idsCounter <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
	<span style="color: #006600; font-style: italic;">//this counter is used to hold positions in the classCounter array.</span>
	<span style="color: #000066; font-weight: bold;">var</span> classCounter <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">//scrape the page for all elements</span>
	<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> elements.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
	    <span style="color: #000066; font-weight: bold;">var</span> current <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span>elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>current.<span style="color: #660066;">length</span><span style="color: #339933;">&gt;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
	    <span style="color: #009900;">&#123;</span>
		output <span style="color: #339933;">+=</span> elements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;{}&lt;br /&gt;&quot;</span><span style="color: #339933;">;</span>
		elementCounter<span style="color: #339933;">++;</span>
		<span style="color: #006600; font-style: italic;">//now that we have an array of a tag, we want to check it for IDs and classes.</span>
		<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">var</span> y <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> y<span style="color: #339933;">&lt;</span>current.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
		    <span style="color: #006600; font-style: italic;">//check to see if the element has an id</span>
		    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>current<span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">id</span><span style="color: #009900;">&#41;</span>
		    <span style="color: #009900;">&#123;</span>
		        <span style="color: #006600; font-style: italic;">//these should be unique, but you never know... here's a bool we'll use to keep track of collisions.</span>
			<span style="color: #000066; font-weight: bold;">var</span> hit <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
			<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> x<span style="color: #339933;">&lt;</span>foundIds.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
			    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>foundIds<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #339933;">==</span>current<span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">id</span><span style="color: #009900;">&#41;</span>
			    <span style="color: #009900;">&#123;</span>
			        hit<span style="color: #339933;">=</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
			    <span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
			<span style="color: #006600; font-style: italic;">//if there was no hit...</span>
			<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>hit<span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
			    foundIds<span style="color: #009900;">&#91;</span>idsCounter<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>current<span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">id</span><span style="color: #339933;">;</span>
			    idsCounter<span style="color: #339933;">++;</span>
			    output<span style="color: #339933;">+=</span><span style="color: #3366CC;">&quot;#&quot;</span> <span style="color: #339933;">+</span> current<span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">id</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;{} &lt;br /&gt;&quot;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
                    <span style="color: #009900;">&#125;</span>
                    <span style="color: #006600; font-style: italic;">//now we pull the classes</span>
		    <span style="color: #000066; font-weight: bold;">var</span> classes <span style="color: #339933;">=</span> current<span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">classList</span><span style="color: #339933;">;</span>
		    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>classes.<span style="color: #660066;">length</span><span style="color: #339933;">&gt;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
		    <span style="color: #009900;">&#123;</span>
		        <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">var</span> x <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> x<span style="color: #339933;">&lt;</span>classes.<span style="color: #660066;">Length</span><span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
		        <span style="color: #009900;">&#123;</span>
		            <span style="color: #006600; font-style: italic;">//now we verify we haven't already listed this class. we'll use a bool to keep track of colisions.</span>
			    <span style="color: #000066; font-weight: bold;">var</span> hit <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
			    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">var</span> z <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> z<span style="color: #339933;">&lt;</span>foundClasses.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> z<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
			    <span style="color: #009900;">&#123;</span>
			        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>foundClasses<span style="color: #009900;">&#91;</span>z<span style="color: #009900;">&#93;</span><span style="color: #339933;">==</span>classes<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
			        <span style="color: #009900;">&#123;</span>
			            hit<span style="color: #339933;">=</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
			        <span style="color: #009900;">&#125;</span>
			    <span style="color: #009900;">&#125;</span>
&nbsp;
			    <span style="color: #006600; font-style: italic;">//if there was not a hit</span>
			    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>hit<span style="color: #009900;">&#41;</span>
			    <span style="color: #009900;">&#123;</span>
			        foundClasses<span style="color: #009900;">&#91;</span>classCounter<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>classes<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			        classCounter<span style="color: #339933;">++;</span>
			        output<span style="color: #339933;">+=</span><span style="color: #3366CC;">&quot;.&quot;</span> <span style="color: #339933;">+</span> classes<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;{} &lt;br /&gt;&quot;</span><span style="color: #339933;">;</span>
			    <span style="color: #009900;">&#125;</span>
		        <span style="color: #009900;">&#125;</span>
		    <span style="color: #009900;">&#125;</span>
	        <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #006600; font-style: italic;">//finally we send the output back to whatever made the call - which we assume is popup.js.</span>
        sendResponse<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>farewell<span style="color: #339933;">:</span> output<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">else</span><span style="color: #009900;">&#123;</span>
        sendResponse<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//the request wasn't sent with the correct string. We send nothing back..</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Finally we have the popup.js, which is more simple.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">//this first line tells chrome to get the user's current tab, which it stores to the variable &quot;tab.&quot;</span>
chrome.<span style="color: #660066;">tabs</span>.<span style="color: #660066;">getSelected</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span><span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>tab<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">//This tells chrome to send a message to the background file (content.js in this extension's case) for the current tab.</span>
	chrome.<span style="color: #660066;">tabs</span>.<span style="color: #660066;">sendMessage</span><span style="color: #009900;">&#40;</span>tab.<span style="color: #660066;">id</span><span style="color: #339933;">,</span> 
		<span style="color: #009900;">&#123;</span>
			greeting<span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;gimmieyodatas&quot;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
                <span style="color: #006600; font-style: italic;">//This tells chrome what to do with the response. In this case, we're binding it to the paragraph in our popup.html with the id &quot;results.&quot;</span>
		<span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>response<span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;results&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">innerHTML</span><span style="color: #339933;">=</span>response.<span style="color: #660066;">farewell</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>So to recap: our manifest file tells Chrome what our extension does, what resources(files) it uses, it&#8217;s name, and other information that may/may not be surfaced to the user. The &#8220;content.js&#8221; file works in the background, and will run constantly on any page where we have a match. The icon and popup.html files are what we present to the user. The popup.js file binds everything else together. </p>
<p>So, now you&#8217;ve got a bunch of files. Now what? Well, toss them in a folder on your desktop (or wheverever), click the wrench icon in chrome, then click &#8216;Settings.&#8217; From there click &#8216;Extensions&#8217; and then click the checkbox for &#8220;developer mode.&#8221; Click the button that says &#8220;Load Unpacked Extension&#8221; and then select the folder you created. Make sure the extension is enabled, and you should see your icon loaded in the top-right corner of chrome. Click the icon, and view the results of your labor. You may need to restart chrome for the plugin to work.</p>
<p>Can this be optimized? Is there a better way to do this? Did I help you out? Let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.billdlabs.com/?feed=rss2&#038;p=17</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>dMinion 2.1 is out!</title>
		<link>http://www.billdlabs.com/?p=13</link>
		<comments>http://www.billdlabs.com/?p=13#comments</comments>
		<pubDate>Tue, 27 Mar 2012 20:42:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Android Applications]]></category>
		<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.billdlabs.com/?p=13</guid>
		<description><![CDATA[Last night I released dMinion 2.1. The new version has an improved layout, the ability to save/load characters, and a tracker for rounds and turns. You can get the new version here. We are also awaiting approval on the Amazon App Store so the app can be loaded on your (and my) Kindle fire.]]></description>
				<content:encoded><![CDATA[<p>Last night I released dMinion 2.1. The new version has an improved layout, the ability to save/load characters, and a tracker for rounds and turns.</p>
<p>You can get the new version <a title="dMinion" href="https://play.google.com/store/apps/details?id=com.billdlabs.dMinion">here</a>.</p>
<p>We are also awaiting approval on the Amazon App Store so the app can be loaded on your (and my) Kindle fire.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.billdlabs.com/?feed=rss2&#038;p=13</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>We are live.</title>
		<link>http://www.billdlabs.com/?p=5</link>
		<comments>http://www.billdlabs.com/?p=5#comments</comments>
		<pubDate>Tue, 13 Sep 2011 12:27:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.billdlabs.com/?p=5</guid>
		<description><![CDATA[After numerous distractions, side projects, and dilly-dalling it is finally go time. My Android developer application has been approved. I&#8217;ve got a few sites in my portfolio, and I&#8217;m just about done with my first for-public-consumption application. I&#8217;m hoping to have an application launched by the end of the week. Once that is done I&#8217;ll [...]]]></description>
				<content:encoded><![CDATA[<p>After numerous distractions, side projects, and dilly-dalling it is finally go time. My Android developer application has been approved. I&#8217;ve got a few sites in my portfolio, and I&#8217;m just about done with my first for-public-consumption application.</p>
<p>I&#8217;m hoping to have an application launched by the end of the week. Once that is done I&#8217;ll turn my attention to designing a layout for this site.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.billdlabs.com/?feed=rss2&#038;p=5</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
