change language

Use IE7Pro User Plugin
User Plugin
Are your tired of copy&paste urls to download youtube video? Now it's even easier!


Mouse Gesture Tutorial

How to write an plugin for IE7Pro

1. General infomation

All plugin file located in <IE7Pro Installation Directory>/plugins/<plugin name>/plugin.js .
We only support one javascript file now( all functions must be in this file).It must be named as "plugin.js".


for example:
c:\program files\ie7pro\plugins\serverinfo\plugin.js
And you need the next header for plugin.js
// ==UserScript==
// @name testplugin
// @namespace http://www.artefxdesign.com/greasemonkey
// @description Adds Netflix search links to IMDb pages
// @statussize 80
// ==/UserScript==
@name must be an unique id compare to other plugins.
@statussize is the width of status bar display area for this plugin.

2. Current Support APIs:

(1) PRO_setValue(name, value)
Allows user script authors to persist simple values locally.
(2) PRO_getValue(name, default)
Retrieve a value set with setValue. If the value is not found, default is returned instead.
(3) PRO_log(msg)
Output the debug message. you need install debugview to see the msg.
http://www.microsoft.com/technet/sysint … gview.mspx
(4) PRO_openInTab(url, flags)
Open an new tab.
flags:0=Current Tab, 1= New Tab Foreground, 2= New Tab Background
(5) PRO_addStyle(css)
Adds a string of CSS to the document.
(6) var httpreq = PRO_xmlhttpRequest();
Same as XMLHTTPRequest but can make an xmlhttp request to other domains.
http://msdn2.microsoft.com/en-us/library/ms535874.aspx
(7) var plugin = PRO_plugin(@name);


Methods:
1) registerContextMenu(name, func)
registerContextMenu("separator"); // add an separator for menu
function prototype: menuCommand(cookie, url)
2) setStatusInfo(imgurl, text, tip, cookie)
3) popupWindow(url, width, height, cookie)
URL support local path:ie7pro://pluginpath/foo.png


Properties:
1) onpagechange
fire when url change. state:1=page loading, 2= page loaded
function prototype: handlePageChange(cookie, url, state)
2) ontabcreate
fire when Tab created.
function prototype: handleTabCreate(cookie)
2) onpopupclose
fire when the window which opened by popupWindow closed.
function prototype: handlePopupClose(url)


3. User scripts

User scripts support all above APIs except PRO_plugin.
User scripts are executed after the DOM is fully loaded, but before onload occurs.
They are executed in an environment very much like regular DHTML scripts are, and executed completely in the content document.

4. Example : Alexa rank and Google Pagerank Plugin

// ==UserScript==
// @name Alexa rank/google pagerank
// @namespace http://www.alexa.com
// @description Display web site Alexa Rank & Google Rank(Thanks [email protected])
// @statussize 160
// ==/UserScript==

(function()
{
var plugin = PRO_plugin(@name);
plugin.onpagechange = handlePageChange;
plugin.registerContextMenu("Show Google results from this site", menuShowGoogleResult);
plugin.registerContextMenu("Show Google Related Site", menuShowGoogleRelated);
plugin.registerContextMenu("Show Alexa Overview", menuShowAlexaOverview);
plugin.registerContextMenu("Show Alexa Traffic Detail", menuShowAlexaTraffic);

var gCookie = "";
var gAlexaRank = "";
var gGoogleRank = "";

var reqObj = new Object();
reqObj.request = function(callback, cookie, url, userAgent, lastModify) {
var req;
req = PRO_xmlhttpRequest();
req.onreadystatechange = function() {
if (req.readyState == 4) {// completed
if (req.status < 400) {// only if "OK"
try {
callback(true, req, cookie);
} catch(err) {
}
} else {
// PRO_log("There was a problem loading data :\n" + req.status+ "/" + req.statusText);
callback(false, req, cookie);
}
setTimeout(function() {req.forceClean();req = null;}, 1000);
}
}
try {
req.open("GET", url);
req.setRequestHeader( "User-Agent", userAgent);
if(lastModify.length > 0)
req.setRequestHeader( "If-Modified-Since", lastModify);
req.send(null);

} catch(err){
}
return req;
}

// escape the url
function encodeURL(url)
{
return escape(url).replace(/\+/g, '%2B').replace(/\"/g, '%22').replace(/\'/g, '%27');
}

function menuShowGoogleResult(cookie,url) {
PRO_openInTab("http://google.com/search?&q=site:"+url,1);
}

function menuShowGoogleRelated(cookie,url) {
PRO_openInTab("http://www.google.com/search?q=related:"+url,1);
}

function menuShowAlexaOverview(cookie,url) {
var urlhost = url.split("/");
var qhost = urlhost[2];
PRO_openInTab("http://www.alexa.com/data/details/main?q=&url="+qhost,1);
}

function menuShowAlexaTraffic(cookie,url) {
var urlhost = url.split("/");
var qhost = urlhost[2];
PRO_openInTab("http://www.alexa.com/data/details/traffic_details?q=&url="+qhost,1);
}

function handlePageChange(cookie, url, state) {
if(state == 1) {// page loading
var re = /http:\/\/(.*)/i;
var urlhost = url.split("/");

var qhost = urlhost[2];
gCookie = cookie;
gAlexaRank = "";
gGoogleRank = "";
var encodeurl = encodeURL(qhost);
var queryurl = "http://xml.alexa.com/data?cli=10&dat=nsa&ver=quirk-searchstatus&uid=20060101000000&userip=126.12.3.4&url=" + encodeurl;
reqObj.request(processAlexaData, cookie, queryurl, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; Alexa Toolbar)", "Thu, 26 Aug 2002 08:24:16 GMT");

var encodeurl2 = encodeURL(url);
var reqgr = "info:" + url;
var reqgre = "info:" + encodeurl2.replace( "_", "%5F" );
var gGoogleCHCalc = new googlechcalc();
var mGoogleCH = gGoogleCHCalc.googleCH( gGoogleCHCalc.strord( reqgr ) );
mGoogleCH = "6" + gGoogleCHCalc.googleNewCh( mGoogleCH );
queryurl = "http://toolbarqueries.google.com/search?client=navclient-auto&ch=" + mGoogleCH + "&ie=UTF-8&oe=UTF-8&features=Rank&q=" + reqgre;
PRO_log(queryurl);
reqObj.request(processGoogleData, cookie, queryurl, "User-Agent", "Mozilla/4.0 (compatible; GoogleToolbar 2.0.114-big; Windows XP 5.1)");

} else if(state == 2) {// page loaded
}
}

function processAlexaData(isOK, req, cookie) {
//PRO_log(req.responseText);
if(gCookie == cookie) {
if(isOK) {
var re = /TEXT=\"(\d+)\"\/\>/i;
var alexaRank = req.responseText.match(re);
if(alexaRank.length > 1)
gAlexaRank = alexaRank[1];
else
gAlexaRank = "0";
} else {
gAlexaRank = "0";
}
if(gGoogleRank.length > 0) {
processResult();
}
}
}

function processGoogleData(isOK, req, cookie) {
if(gCookie == cookie) {
if(isOK) {
var re = /Rank_.*?:.*?:(\d+)/i;
var googleRank = req.responseText.match(re);
if(googleRank.length > 1)
gGoogleRank = googleRank[1];
else
gGoogleRank = "0";
} else {
gGoogleRank = "0";
}
if(gAlexa.length > 0) {
processResult();
}
}
}

function processResult()
{
plugin.setStatusInfo("", "Alexa:"+FormatInteger(gAlexaRank)+" Google:"+gGoogleRank + "/10", "", gCookie);
}

function googlechcalc() {
return this;
}

googlechcalc.prototype =
{
googleNewCh: function( ch )
{
ch = ( ( ( ch / 7 ) << 2 ) | ( ( this.myfmod( ch,13 ) ) & 7 ) );

prbuf = new Array();
prbuf[0] = ch;
for( i = 1; i < 20; i++ )
{
prbuf[i] = prbuf[i-1] - 9;
}
ch = this.googleCH( this.c32to8bit( prbuf ), 80 );

return ch;
},

googleCH: function( url )
{
var init = 0xE6359A60;

var length = url.length;

var a = 0x9E3779B9;
var b = 0x9E3779B9;
var c = 0xE6359A60;
var k = 0;
var len = length;
var mixo = new Array();

while( len >= 12 )
{
a += (url[k+0] +(url[k+1]<<8) +(url[k+2]<<16) +(url[k+3]<<24));
b += (url[k+4] +(url[k+5]<<8) +(url[k+6]<<16) +(url[k+7]<<24));
c += (url[k+8] +(url[k+9]<<8) +(url[k+10]<<16)+(url[k+11]<<24));
mixo = this.mix(a,b,c);
a = mixo[0]; b = mixo[1]; c = mixo[2];
k += 12;
len -= 12;
}

c += length;

switch( len )
{
case 11:
c += url[k+10]<<24;

case 10:
c+=url[k+9]<<16;

case 9 :
c+=url[k+8]<<8;

case 8 :
b+=(url[k+7]<<24);

case 7 :
b+=(url[k+6]<<16);

case 6 :
b+=(url[k+5]<<8);

case 5 :
b+=(url[k+4]);

case 4 :
a+=(url[k+3]<<24);

case 3 :
a+=(url[k+2]<<16);

case 2 :
a+=(url[k+1]<<8);

case 1 :
a+=(url[k+0]);
}

mixo = this.mix( a, b, c );

if( mixo[2] < 0 )
{
return ( 0x100000000 + mixo[2] );
}
else
{
return mixo[2];
}
},

hexdec: function( str )
{
return parseInt( str, 16 );
},

zeroFill: function( a, b )
{
var z = this.hexdec( 80000000 );

if( z & a )
{
a = a >> 1;
a &= ~z;
a |= 0x40000000;
a = a >> ( b - 1 );
}
else
{
a = a >> b;
}

return (a);
},

mix: function( a, b, c )
{
a -= b; a -= c; a ^= ( this.zeroFill( c, 13 ) );
b -= c; b -= a; b ^= ( a << 8 );
c -= a; c -= b; c ^= ( this.zeroFill( b, 13 ) );
a -= b; a -= c; a ^= ( this.zeroFill( c, 12 ) );
b -= c; b -= a; b ^= ( a << 16);
c -= a; c -= b; c ^= ( this.zeroFill( b, 5 ) );
a -= b; a -= c; a ^= ( this.zeroFill( c, 3 ) );
b -= c; b -= a; b ^= ( a << 10);
c -= a; c -= b; c ^= ( this.zeroFill( b, 15 ) );

var ret = new Array( (a), (b), (c) );

return ret;
},

strord: function( string )
{
var result = new Array();

for( i = 0; i < string.length; i++ )
{
result[i] = string.charCodeAt( i);
}

return result;
},

c32to8bit: function( arr32 )
{
var arr8 = new Array();

for( i = 0; i < arr32.length; i++ )
{
for( bitOrder = i * 4; bitOrder <= i * 4 + 3; bitOrder++ )
{
arr8[bitOrder] = arr32[i] & 255;
arr32[i] = this.zeroFill( arr32[i], 8 );
}
}

return arr8;
},

myfmod: function( x, y )
{
var i = Math.floor( x / y );
return ( x - i * y );
}
};
function FormatInteger( integer )
{
var pattern = "###,###,###,###";
var result = '';

integerIndex = integer.length - 1;
patternIndex = pattern.length - 1;

while( ( integerIndex >= 0 ) && ( patternIndex >= 0 ) )
{
var digit = integer.charAt( integerIndex );
integerIndex--;

// Skip non-digits from the source integer (eradicate current formatting).
if( ( digit < '0' ) || ( digit > '9') ) continue;

// Got a digit from the integer, now plug it into the pattern.
while( patternIndex >= 0 )
{
var patternChar = pattern.charAt( patternIndex );
patternIndex--;

// Substitute digits for '#' chars, treat other chars literally.
if( patternChar == '#' )
{
result = digit + result;
break;
}
else
{
result = patternChar + result;
}
}
}

return result;
}
}
)();

Related Links