一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Google Chrome Extension

 quasiceo 2015-05-31
, 6 Aug 2014 CPOL 75.3K 1K 81
   4.96 (85 votes)
Google Chrome Extension that scrapes your reputation points and graph, and tracks changes between updates.

CodeProject Reputation Extension

Important V2 Changes

Due to the policy change imposed by Google to protect users from harmful code, there were a number of change required to the extension.

 

  • Update of the manifest to new V2 standard.
  • Extension distribution from the Chrome Web Store
  • Removal of inline script blocks from HTML pages.

 

I also took advantage of the changes to upgrade to a new jQuery file and refactor some other code.

Introduction

This article was written as a result of me wanting to try some new topics. In order to try these new topics, it would be better to try and develop a functioning component rather than just play about with code syntax.

This article will explore how to put together a Google Chrome Extension, and also how I utilised jQuery and jQuery UI in building the extension. So what will this extension do? This extension can recover the source of a user's CodeProject profile page and scrape out their reputation points. The extension stores these points locally, and compares the changes between polls to The Code Project, and then presents this information in a nice little table. The extension can also recover the member's reputation graph and display this in the extension.

Background

The information required in building this extension can be found on Google Chrome Extension pages. For information relating to jQuery and jQuery UI, see here and here.

The Chrome Extension

Chrome Extensions are effectively a collection of HTML files with fully embedded JavaScript and CSS, or can link out to other JavaScript, CSS, and image files. In order for Chrome to know what to do with all these files and how to present it to the user, a manifest file in the root of the project defines the various elements. The manifest file must be named 'manifest.json'.

Let's take a look now at the manifest file crafted for this extension:

Hide   Copy Code
{
  "manifest_version": 2,
  "name": "CodeProject Reputation Watcher",
  "short_name": "CPRepWatcher",
  "version": "2.0",
  "content_security_policy": "script-src 'self' https://ssl. 'unsafe-eval'; object-src 'self' ",
  "description": "Extension to retrieve a CodeProject accounts reputation points.",
  "icons": {
      "48":"images/bob48.png",
      "128":"images/bob128.png"
  },
  "browser_action": {
    "default_icon": "images/bob.png",
    "default_popup": "cprepwatch.html"
  },
  "options_page": "options.html",
  "permissions": [
    "http://*./"
  ]
}

There are some basic attributes like 'name', 'version', and 'description', which are self-explanatory. The 'icons' element defines which images are available for use by the extension; these appear in the Chrome Extensions page when it is installed.

The 'browser_action' element tells Chrome which icon to show in the toolbar and which HTML file is the main popup when the extension icon is clicked.

The 'options_page' element tells Chrome which HTML page will be displayed to allow the user to set any options/user settings used by the extension. This page is accessed from the Options menu displayed when the toolbar button is right-clicked, or from the Options link on the Chrome Extensions page accessed from the Tools menu of Chrome.

The 'permissions' element defines which site the extension wants to access, and is used by the cross site security model.

(Manifest Version 1) The 'update_url' element defined the XML file used by the Auto Update tool to check for newer revisions of the extension. As of Version 2, this is no longer required as the extension is hosted through the Chrome store. Chrome Browser takes care of the version update process. This property was susequently removed.

You can also see the 'manifest_versions' and 'content_security_policy' changes that were required under the new rules. One other thing I noted was that the uploader to the chrome store did not like having comment lines in the manifest, so had to also remove these. This was only discovered by trial and error as the error message wasn't very helpful.

There are several other elements that can be added to the manifest file depending on your requirements; there are details of these on the Chrome Extensions developers page.

Adding jQuery and jQuery UI

To make use of these JavaScript libraries, you need to download them first from the developers site, here, and here. On the jQuery UI site, there are also a number of predefined themes that can be used with the UI elements, and you can also create your own using the website's theme generator. After you have downloaded the zip files with the libraries and themes, unpack these and add them to your project folder. Every page that wants to make use of these libraries must have them linked in the HTML. This is easily achieved using standard markup.

Hide   Copy Code
<link type="text/css" 
      href="css/custom-theme/jquery-ui-1.8.2.custom.css" rel="Stylesheet" />
<script type="text/javascript" src="jquery/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="jquery/jquery-ui-1.8.2.custom.min.js"></script>
<script type="text/javascript" src="js/cpjshelper.js"></script>

You will also notice that there is a reference to a 'js/cpjshelper.js' JavaScript file. As the extension was developed, common shared helper functions were moved out to this file, to maximise code re-use and keep the HTML files neater.

Why Use jQuery?

jQuery provides an excellent method for manipulating and traversing the DOM. It certainly made things very easy once I had got my head round the syntax, which doesn't take too long. Here are some basic examples of what it can do:

Hide   Copy Code
//Insert some HTML into a Div element named 'holdingdata'
$("#holdingdata").html("the html markup would go here");
$("#anElement").hide();        //Hide an element
$("#anElement").show();        //Show an element
$("p").each(function(){ $(this).hide();});
//Find all 'p' tags and hide them

The jQuery command below executes a function when the browser document has loaded. The function sets up a timer which calls another function after a period of time. .get() performs an AJAX query using HTTP GET and then passes the returned data onto another function for processing. The AJAX calls can be made synchronous or asynchronous depending on your requirements. The two helper functions are JavaScript functions written to deal with the CodeProject addresses and data.

Hide   Copy Code
$(document).ready(function () {
    setTimeout(function () {
        //Start loading the data from Codeproject profile
        $.get(getCPMemberProfile(), function (data) {
            setCPProfileData(data);
        });
    }, 1000);
});

This is just a fraction of the full capabilities of jQuery, and if you pop over to the developer site and explore the documentation, you will soon see what I mean.

Why Use jQuery UI?

jQuery UI provides a comprehensive set of interface widgets that can be plugged into your HTML, and then using the CSS markups, provides a set of rich interface components. In this extension, the components that have been used are the Tabs panel and a basic button.

The Tabs panel was easily created as shown below:

Hide   Copy Code
<script type="text/javascript">
                       $(function() {
                           $("#tabs").tabs();
                       });
</script>
<div id="tabs" style="height: 400px;">
    <!-- Tab Pages -->
    <ul>
        <li><a href="#tabs-1">Reputation Points</a></li>
        <li><a href="repgraph.html">Reputation Graph</a></li>
        <li><a href="#tabs-3">Options</a></li>
        <li><a href="about.html">About</a></li>
    </ul>
    <!-- Tab 1 Rep Points -->
    <div id="tabs-1" style="padding-left: 5px">
        <!-- Main Rep Page content -->
    </div>
    <!-- Tab 2 Rep Graph ; Note: This does not require a section 
           as it is a link URL in tab definition above. -->
    <!-- Tab 3 Options -->
    <div id="tabs-3" style="padding-left: 5px">
        <!-- Options Tab Content goes Here -->
    </div>
    <!-- Tab 4 About ; Note: This does not require a section 
            as it is a link URL in tab definition above. -->
</div>

You will also notice that Tab 2 (Rep Graph) and Tab 4 (About) are references to an external document within the extension files. This content is loaded via AJAX, and then injected into the current page's DOM at the relevant tab location.

Scraping the CodeProject Content

In order to retrieve the CodeProject content, a JavaScript function first loads the member profile page by using an AJAX call. The returned content is then placed in a hidden Div block on the page, which can then be accessed, traversed, and parsed using jQuery. There were three main Elements on the CodeProject content which were used to identify the areas to be scraped. These were 'ctl00_MC_Prof_TotalRepBox' for the overall member level, 'ctl00_MC_Prof_TotalRep' for the total reputation points, and 'ctl00_MC_Prof_Status' for all the individual category points.

Hide   Copy Code
//The Total Reputation Member Level is Found in
if ($("#ctl00_MC_Prof_TotalRepBox").hasClass("nostatus")) { $("#repStatus0").html(" "); };
if ($("#ctl00_MC_Prof_TotalRepBox").hasClass("bronze")) { $("#repStatus0").html("Bronze"); };
if ($("#ctl00_MC_Prof_TotalRepBox").hasClass("silver")) { $("#repStatus0").html("Silver"); };
if ($("#ctl00_MC_Prof_TotalRepBox").hasClass("gold")) { $("#repStatus0").html("Gold"); };
if ($("#ctl00_MC_Prof_TotalRepBox").hasClass("platinum")) 
              { $("#repStatus0").html("Platinum"); };

//The Total Reputation is found in this node
var thestring = $("#ctl00_MC_Prof_TotalRep");
if (thestring) { newRep[0] = thestring.text(); } else { newRep[0] = "0"; }
$("#loadRepTotal").html(newRep[0]);

//Reputation Points table
holdingdata.innerHTML = $('table.member-rep-list').html();

Once the content had been located and copied into the holding Div, jQuery was then used to extract the text from the inner element. Below is the code that is used to locate each TableRow, and then within each one, find each TableData and locate the Points, Category, and Status level, and then inject them into the DOM for presenting to the user.

Hide   Shrink   Copy Code
$("#holdingdata").find("tr").each(function (iTR) {
    $(this).find("td").each(function (iTD) {
        var MemberLevel = "";
        if ($(this).hasClass("nostatus")) { MemberLevel = "" };
        if ($(this).hasClass("bronze")) { MemberLevel = "Bronze" };
        if ($(this).hasClass("silver")) { MemberLevel = "Silver" };
        if ($(this).hasClass("gold")) { MemberLevel = "Gold" };
        if ($(this).hasClass("platinum")) { MemberLevel = "Platinum" };
         
         
         //Version 1.6 21st March 2011, Additional second link in each category
         //iterate all the links determining a Category/Value pair
         var thevalue = $(this).find("div.medium-text").text();
         if (!thevalue) { thevalue = ""; 
         $(this).find("a").each( function (iA) {
            var category = $(this).text();             
            var category = $(this).find("a").text();

            if (!category) { category = "No Data"; };
            category = category.toUpperCase(category);            
            switch (category) {
                case ("AUTHOR"):
                    newRep[1] = thevalue;
                    $("#loadRepAuthor").html(newRep[1]);
                    $("#repStatus1").html(MemberLevel);
                    break;
                case ("AUTHORITY"):
                    newRep[2] = thevalue;
                    $("#loadRepAuthority").html(newRep[2]);
                    $("#repStatus2").html(MemberLevel);
                    break;
                // Other case statements
                    for the other categories continue...........
            }
        });
    });
});

Testing Code

In order to test the code, first load the unpackaged extension into Chrome. To do this, you select 'Tools', then the 'Extensions' menu, expand the developer panel, and then select 'Load unpacked extension...', and navigate to the folder which contains all the files used in the extension. The extension will be loaded, shown as unpacked, and the icons, etc., specified in the manifest should appear in the toolbar and also to the left of the extension.

To see what is going on under the hood, you can right click the toolbar and select 'Inspect Pop-up' and look for errors, see what is being stored in the local storage, etc. As you revise the codebase/HTML files, simply click 'Reload' in extensions to update it.

To aid testing, you can place some JavaScript code in your extension to output to the Chrome debugger; this is as simple as:

Hide   Copy Code
//Output the contents of a variable to the debugger
console.log(variablename);
//Output a string to the debugger
console.log("Some text.");

Local Storage of Data/Settings

Objects can be stored locally, and in this extension, the CodeProject member ID as well as the reputation points for the last data poll are stored. Persisting the data is easy, and as you can see below, it is also easy to recall the data when required.

Hide   Copy Code
// Put data in the local store
var sometext = "Hello";
localStorage["AnyKeyName"] = sometext;

// Get data from the local store
var sometext;
sometext = localStorage["AnyKeyName"];

// Test the data does exist and was read
if (!sometext)
{
    // The data is not present in the local store
}

Packaging and Deployment/Hosting

There are two methods of distribution of the extension:

  1. Unpackaged method, which although works, is really suited to testing and development scenarios
  2. Google hosting via the Chrome Web Store.

The unpackaged extension is available to download from this article and the extension has also been published to the Chrome Web Store.

Packaged Extensions are no longer permitted. These will be blocked by the browser and disabled.

For more information on Packing, Deployment, and Google Hosting, see Extension Packaging.

How Can I Use This Extension?

You can either download and install the unpackaged extension, or click the link above to install from the web store.

NOTE: Installing the unpacked extension (in developer mode) from the Tools | Extension menu will allow you to install from the source. The browser will however keep reminding you and asking if you want to disable this mode.

Once you have installed by either method, then all you need to do is from the Options menu item, Extensions Options link, or from the Options tab on the actual extension, set this to your CodeProject member ID. Your member ID can be found on your profile page for your account.

Every time you click the Extensions Toolbar button, it will display the page shown at the top of the article and update the table with your latest points.

The other tabs on the extension can be seen below: Rep Graph, Options, and About.

Extension Removal

After you install an extension, it's just a case of hitting the uninstall link and deleting the source folder where you unzipped the unpackaged extension.

What Next

The codebase isn't probably the most optimised, so could do with a tidy up, but as usual, once it is working, I was reluctant to change anything. If I get time, I might look into this and possibly add some other features, like auto refresh.

Tracking Usage and User Interaction

It is possible to track usage of the extension by adding Google Analytics code to the files. From this, you can track which pages are being viewed, which buttons get clicked etc. More information on Analytics integration can be found here.

Points of Interest

As this was my first adventure in Chrome Extensions, jQuery, and jQuery UI, it was certainly a challenge, which has proved very rewarding.

Known Issues

There appears to be a weird cache related problem in Chrome, which is only an issue if you enter an invalid CodeProject member ID: e.g., navigate to your member profile, then navigate to an invalid profile, navigate to someone else's profile, navigate to the same invalid profile, and you will see your member profile entered at the start appears... I can't explain this, and for normal use of the extension, it doesn't matter anyway. As long as you use a valid member ID: things will be fine.

History

(Version numbers relate to code changes, not article revisions.)

  • V2.0 18th June 2014 - Updated to the new Chrome requirements, jQuery updated to V1.11.1
  • 23 October 2013 - Update installation instructions due to Chrome changes
  • V1.6, 21 March 2011 - Updated for CodeProject DOM/Member Profile changes
  • V1.5, 13 December 2010 - Updated for CodeProject DOM changes
  • V1.4, 20 October 2010 - Added Overall Member Level
  • V1.3, 10 September 2010 - Resolved some Google Analytics issues
  • V1.2, 9 September 2010 - Fixed some JS errors, moved the About content to a standalone file and called via AJAX, added Google Analytics tracking. Also introduced Package & Deployment to private web server details to the article
  • V1.1, 4 August 2010 - Fixed to handle new CSS class IDs for member status; removed redundant CSS theme from zip file
  • V1.0, 1 August 2010 - First version of article

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

DaveAuld
Engineer
Scotland Scotland
I have been working in the Oil & Gas Industry for over 25 years now.

Core Discipline is Instrumentation and Control Systems.

Completed Bsc Honours Degree (B29 in Computing) with the Open University in 2012.

Currently, Offshore Installation Manager in the Al Shaheen oil field, which is located off the coast of Qatar.

Prior to this, 25 years of North Sea Oil & Gas experience.
Follow on   Twitter   Google+   LinkedIn


Comments and Discussions

 
You must Sign In to use this message board.
Search Comments  

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    黄色国产精品一区二区三区| 人妻偷人精品一区二区三区不卡| 国产成人国产精品国产三级| 国产不卡视频一区在线| 欧美日韩综合在线第一页| 亚洲成人精品免费在线观看| 日韩欧美一区二区黄色| 欧美多人疯狂性战派对| 亚洲男人天堂成人在线视频| 亚洲中文字幕视频在线播放| 国产又大又猛又粗又长又爽| 国产精品欧美激情在线| 欧美成人免费夜夜黄啪啪 | 加勒比系列一区二区在线观看 | 91亚洲精品国产一区| 大香蕉伊人一区二区三区| 伊人天堂午夜精品草草网| 丁香六月啪啪激情综合区| 加勒比人妻精品一区二区| 日本 一区二区 在线| 久久精品国产第一区二区三区| 美女被后入福利在线观看| 色综合伊人天天综合网中文 | 国产欧美一区二区另类精品| 国产又粗又猛又长又大| 熟女白浆精品一区二区| 欧美日韩国产自拍亚洲| 国产亚洲精品俞拍视频福利区| 富婆又大又白又丰满又紧又硬| 欧美日韩无卡一区二区| 亚洲一区二区精品久久av| 欧美午夜一区二区福利视频| 日韩欧美黄色一级视频| 91午夜少妇极品福利| 日本午夜免费观看视频| 好吊视频有精品永久免费| 日韩一区二区三区嘿嘿| 日韩成人中文字幕在线一区 | 日本深夜福利视频在线| 久久国产人妻一区二区免费| 国产女性精品一区二区三区|