鲜果 Plus | Xianguo Plus
By CIH
—
Last update Jul 9, 2008
—
Installed
293 times.
Add Syntax Highlighting (this will take a few seconds, probably freezing your browser while it works)
// ==UserScript==
// @name 鲜果 Plus | Xianguo Plus
// @namespace http://userstyles.org
// @description 对鲜果RSS阅读器进行了增强和优化
// @version 0.41
// @author CIH
// @homepage http://blog.recih.cn/xianguo-plus
// @include http://www.xianguo.com/reader/
// ==/UserScript==
const DEBUG = false;
var console =
{
log : function (text) { if( DEBUG ) unsafeWindow.console.log( text ); },
info : function (text) { if( DEBUG ) unsafeWindow.console.info( text ); },
warn : function (text) { if( DEBUG ) unsafeWindow.console.warn( text ); },
error : function (text) { if( DEBUG ) unsafeWindow.console.error( text ); }
}
var SITE_INFO =
[
{
feedId: 43,
template: "<xsl:template match=\"/\">\n<div>\n\t<xsl:copy-of select=\"id('news_content')/div[@class='digbox']/preceding-sibling::*\" />\n</div>\n<hr />\n<h3>热门评论</h3>\n<xsl:for-each select=\"id('g_content')/dl\">\n\t<div class=\"xianguo-plus-comment\">\n\t\t<div class=\"title\"><xsl:value-of select=\"dt[@class='re_author']\" /></div>\n\t\t<xsl:copy-of select=\"dd[@class='re_detail']/node()\" />\n\t\t<div><xsl:copy-of select=\"dd[@class='re_mark']/node()\" /></div>\n\t</div>\n</xsl:for-each>\n</xsl:template>",
charset: "gb2312"
}
];
var css =
<style><![CDATA[
@namespace url(http://www.w3.org/1999/xhtml);
#context_itemList .item {
margin-left: 5px !important;
margin-right: 5px !important;
opacity: 0.5;
border: 2px solid #e0e0e8 !important;
-moz-border-radius: 10px;
}
#context_itemList .item_selected {
opacity: 1;
border: 2px solid #83AFF0 !important;
-moz-border-radius: 10px;
}
.item_bottom {
background-color: #EEEEEE;
-moz-border-radius-bottomleft: 8px;
-moz-border-radius-bottomright: 8px;
}
.item_header .header_left {width: 68% !important;}
.itemPannel_hr {background-color: white !important; height: 5px !important;}
#xianguoPlusFullFeedPanelDiv {
position:fixed;
height:432px;
width:350px;
background-color:#C1D8F9;
border:1px solid #919B9c;
font-size:12px;
padding:8px;
display:none;
}
.item_descr {position: relative;}
.xianguo-plus-loading {
position: absolute;
right: 15px;
top: 0;
height: 18px;
padding: 2px;
background-color: #EA0000;
color: white;
}
.xianguo-plus-comment {margin-bottom: 8px; border: 1px solid #D3D3D3; padding: 8px; -moz-border-radius: 5px;}
.xianguo-plus-comment .title {display: block; color: #4A7BB5; background-color: #CDEBFE; padding: 8px;}
]]>
</style>
css = css.text();
if (typeof GM_addStyle != "undefined") {
GM_addStyle(css);
} else if (typeof addStyle != "undefined") {
addStyle(css);
} else {
var heads = document.getElementsByTagName("head");
if (heads.length > 0) {
var node = document.createElement("style");
node.type = "text/css";
node.appendChild(document.createTextNode(css));
heads[0].appendChild(node);
}
}
function $(id) {
return unsafeWindow.document.getElementById(id);
}
function $x(p, context) {
if (!context) context = document;
var i, arr = [], xpr = document.evaluate(p, context, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
for (i = 0; item = xpr.snapshotItem(i); i++) arr.push(item);
return arr;
}
function $$(xpath,root) {
xpath=xpath.replace(/((^|\|)\s*)([^/|\s]+)/g,'$2.//$3').
replace(/\.([\w-]+)(?!([^\]]*]))/g,'[@class="$1" or @class$=" $1" or @class^="$1 " or @class~=" $1 "]').
replace(/#([\w-]+)/g,'[@id="$1"]').
replace(/\/\[/g,'/*[');
str='(@\\w+|"[^"]*"|\'[^\']*\')'
xpath=xpath.replace(new RegExp(str+'\\s*~=\\s*'+str,'g'),'contains($1,$2)').
replace(new RegExp(str+'\\s*\\^=\\s*'+str,'g'),'starts-with($1,$2)').
replace(new RegExp(str+'\\s*\\$=\\s*'+str,'g'),'substring($1,string-length($1)-string-length($2)+1)=$2');
var got=document.evaluate(xpath,root||document,null,null,null), result=[];
while(next=got.iterateNext()) result.push(next);
return result;
}
function extend(destination,source)
{
for(property in source)
{
destination[property]=source[property];
}
return destination;
};
String.prototype.trim = function()
{
return this.replace(/(^\s+|\s+$)/g,'');
}
function $import()
{
var script = [];
for(var i=0; i<arguments.length; i++)
{
var varName = arguments[i];
script.push("var " + varName + " = unsafeWindow." + varName + ";");
}
return script.join("");
}
eval($import(
"ItemList",
"Actor",
"PageMgr",
"PanelMgr",
"TabMgr",
"JSON",
"WaitControl",
"AsyncCall",
"interfaceUrl",
"htmlToFragment",
"ChannelList",
"UBB",
"setTimeout"
));
var _feedInitMenu = ChannelList.Feed.initMenu;
ChannelList.Feed.initMenu = function()
{
_feedInitMenu.call(ChannelList.Feed);
var menu = ChannelList.Feed.menu;
menu.addGroupItem('menuitem_line');
menu.addItem('Feed全文设置...',function(){Panel.FullFeed.show(ChannelList.Feed.FeedID);});
}
var Panel=
{
extend: function(obj)
{
obj.getValue = Panel.getValue;
obj.setValue = Panel.setValue;
obj.getElement = Panel.getElement;
return obj;
},
onLoad: function(event)
{
for(var prop in Panel)
{
if(typeof Panel[prop] == "function")
{
continue;
}
var panel = Panel[prop];
if(typeof panel.onLoad == "function")
{
panel.onLoad(event);
}
}
},
getElement: function(name)
{
return $x("id('" + this.id + "')//*[@name='" + name + "']")[0];
},
getValue: function(name)
{
if(name)
{
var el = this.getElement(name);
return el ? el.value : undefined;
}
else
{
var els = $x("id('" + this.id + "')//*[@name]");
var result = {};
for(var i=0; i<els.length; i++)
{
var item = els[i];
var name = item.name;
if(name && item.value)
{
result[name] = item.value;
}
}
return result;
}
},
setValue: function(name, value)
{
var el = this.getElement(name);
if(el)el.value = value ? value : "";
}
}
Panel.FullFeed = Panel.extend(
{
id: "xianguoPlusFullFeedPanelDiv",
html:
<div id="xianguoPlusFullFeedPanelDiv">
<span onclick="PanelMgr.hide()" class="close"> </span>
<div id="xianguoPlus.FullFeed.title" style="font-size: 12px; font-weight: bold;">测试</div>
<div style="border: 1px solid #919b9c; background-color: #ddecff; padding: 8px;">
启用:<input type="checkbox" name="disabled" /><br />
Feed ID:<input name="feedId" type="text" disabled="disabled" /><br />
Feed全文模板:(支持XSLT。或者可通过$x{...}使用XPath查找页面元素)<br />
<textarea name="template" style="height: 135px; width: 320px; font-size: 12px; scroll: auto;"> </textarea><br />
网页编码:<input name="charset" type="text" value="utf-8"/><br />
自动读取:<input type="checkbox" name="auto" /><br />
自动读取应用于包含以下关键词的文章:(正则表达式)<br />
<font color="red">如果为空的话将自动读取所有文章</font><br />
<textarea name="keyword" style="height: 50px; width: 320px; font-size: 12px;"> </textarea><br />
<br />
<span style="float: left;">
<button id="xianguoPlus.ok">确定</button>
<button onclick="PanelMgr.hide()">取消</button>
</span>
<span style="float: right;">
<button id="xianguoPlus.remove">删除</button>
</span>
<div class="clear"/>
</div>
</div>,
show: function(feedId)
{
var panel = $(this.id);
if(!panel) return;
var feedId = feedId || ChannelList.currentSelectedId;
var feed = ChannelList.FindChannel(feedId);
var title = feed ? feed.title : "没有标题";
var info = SiteInfo.get(feedId) || {disabled: true, charset: "utf-8"};
this.getElement("disabled").checked = info.disabled != true;
this.setValue("feedId", feedId);
this.setValue("template", info.template);
this.setValue("charset", info.charset);
this.getElement("auto").checked = info.auto == true;
this.setValue("keyword", info.keyword);
$("xianguoPlus.FullFeed.title").innerHTML = title + " - Feed全文设置 ";
PanelMgr.show($(this.id), {});
},
save: function()
{
var info = this.getValue();
info.disabled = !this.getElement("disabled").checked;
if(!info.disabled) delete info.disabled;
info.auto = this.getElement("auto").checked;
if(!info.auto) delete info.auto;
if(info.template && info.template.trim().length > 0)
{
SiteInfo.put(info.feedId, info);
}
else
{
SiteInfo.remove(info.feedId);
}
SiteInfo.save();
},
remove: function()
{
var feedId = this.getValue("feedId");
SiteInfo.remove(feedId);
SiteInfo.save();
},
onLoad: function(event)
{
var div = document.createElement("DIV");
div.innerHTML = Panel.FullFeed.html.toXMLString();
document.body.appendChild(div.firstChild);
$("xianguoPlus.ok").addEventListener("click", function(event)
{
Panel.FullFeed.save();
PanelMgr.hide();
}, false);
$("xianguoPlus.remove").addEventListener("click", function(event)
{
Panel.FullFeed.remove();
PanelMgr.hide();
}, false);
}
});
window.addEventListener("load", Panel.onLoad, false);
var SiteInfo =
{
_info: {},
put: function(feedId, info)
{
this._info[feedId] = info;
},
get: function(feedId)
{
var info = this._info[feedId];
return info ? extend({}, info) : undefined;
},
remove: function(feedId)
{
delete this._info[feedId];
},
save: function()
{
var json = JSON.stringify(SiteInfo._info);
GM_setValue("siteInfo", json);
},
init: function()
{
SITE_INFO.forEach(function(site)
{
SiteInfo.put(site.feedId, site);
});
var json = GM_getValue("siteInfo");
if(json)
{
var info = JSON.parse(json) || {};
for(var feedId in info)
{
var site = SiteInfo._info[feedId];
if(site)
{
extend(site, info[feedId]);
}
else
{
SiteInfo._info[feedId] = info[feedId];
}
}
}
}
}
SiteInfo.init();
var ContentCache =
{
MAX_SIZE: 50,
_content: {},
_index: [],
put: function(id, content)
{
this._index.push(id);
this._content[id] = content;
if(this.size() > this.MAX_SIZE)
{
var first = this._index.shift();
delete this._content[first];
}
},
get: function(id)
{
return this._content[id];
},
clear: function()
{
this._content = {};
this._index = [];
},
size: function()
{
return this._index.length;
}
}
var _init = ItemList.Init;
ItemList.Init = function()
{
ItemList.isAppending = false;
return _init();
}
ItemList.scrollToItem=function(index)
{
if(index<0||index>=ItemList.cShowCount||!ItemList.scrollEnable)return;
var firstTop = $("item_" + ItemList.cList[0].feedItemId).offsetTop;
var scroll = $("item_" + ItemList.cList[index].feedItemId).offsetTop - firstTop;
if(!Actor.UserConfig.full_scroll)
{
$('context_itemList').scrollTop=scroll;
}
else
{
$('content_pannel').scrollTop=scroll+$('header_pannel').offsetHeight+$('itemList_header').offsetHeight;
}
}
ItemList.openCurrentItem=function()
{
if(!PageMgr.inItemList()||ItemList.cSelectedItemIndex===null)return;
var item=ItemList.cList[ItemList.cSelectedItemIndex];
var siteInfo = SiteInfo.get(item.feedId);
if(siteInfo && !siteInfo.disabled)
{
var container = $("descr_" + item.feedItemId);
var loading = $x("div[@class='xianguo-plus-loading']", container)[0];
var xianguoPlus = $x("div[@class='xianguo-plus-content']", container)[0];
if(!loading && !xianguoPlus)
{
setTimeout(function(){
Fetcher.request(item, container, siteInfo);
},1);
return;
}
}
var url = 'http://www.xianguo.com/go.php?fi=' + item.feedItemId;
GM_openInTab(url);
}
var _selectItem = ItemList.selectItem;
ItemList.selectItem=function(index,onlyFocus)
{
var result = _selectItem(index, onlyFocus);
if(ItemList.cList.length - index <= 7)
{
if(!ItemList.isAppending)
{
ItemList.isAppending = true;
ItemList.appendNextPage();
}
}
return result;
}
ItemList.appendNextPage=function()
{
var page = ItemList.cPage + 1;
if(!page)return;
if(page<0||page>this.cTotalPage)return;
if(!$('itemList_footer_filp'))return;
ItemList.isRefreshing=true;
var loader=$('itemList_footer_filp').loader;
if(loader){
eval("unsafeWindow."+loader+"("+page+")");
}
else
{
ItemList.load(page);
}
}
ItemList.load=function(page,onComplete,onError){
if(page){
ItemList.params.page=page-1;
ItemList.cPage=page;
}
var params='method='+ItemList.method+'¶ms='+JSON.serialize(ItemList.params);
if(!ItemList.isAppending)
{
WaitControl.PannelWait();
}
AsyncCall(interfaceUrl,params,function(res){
var ret=eval('('+res.responseText+')');
if(ret.status==0){
if(onError)onError(ret);
return;
}
try{
var title=ItemList.getTitle()||'';
if(!ItemList.isAppending)
{
ItemList.GoPageHead();
if(ItemList.isRefreshing||ItemList.cPage>1){
$('context_itemList').innerHTML='';
}else{
ItemList.LoadRange();
ItemList.SwitchUnreadModeHtml();
ItemList.SwitchListModeHtml();
ItemList.showOptionLabel(true);
ItemList.showChannelSetting(ItemList.isSingleFeed()&&ItemList.status!='preview');
ItemList.setTitle(title);
}
$('context_itemList').focus();
}
ItemList.isRefreshing=false;
if(!ItemList.isAppending)
{
ItemList.cShowCount=0;
ItemList.cSelectedItemId=null;
ItemList.cSelectedItemIndex=null;
}
if(ret.data.feeds)
ItemList.cFeedsMap=ret.data.feeds;
if(onComplete&&onComplete(ret)===false)return;
var list = ret.data.list;
if(!ItemList.isAppending)
{
if(UBB){
for(var i=0;i<list.length;i++){
list[i].description=UBB.toHtml(list[i].description);
}
}
ItemList.cList=list;
}
else
{
for(var i=0;i<list.length;i++){
var item = list[i];
if(UBB){
item.description=UBB.toHtml(item.description);
}
ItemList.cList.push(item);
}
}
ItemList.cListTotal=ret.data.total;
ItemList.cTotalPage=ret.data.totalPage;
//ItemList.showOptionNextPage(ItemList.cPage<ItemList.cTotalPage);
ItemList.showOptionNextPage(false);
ItemList.showPager();
ItemList.ShowList();
}catch(ex){
console.log(ex);
}
},onError);
if(!Actor.isAnonymous() && !ItemList.isAppending){
ItemList.initAnalyzer();
}
}
ItemList.unreadLoad=function(ret){
ItemList.cTotalPage=parseInt(ItemList.cListTotal/Actor.UserConfig.page_size)+(ItemList.cListTotal%Actor.UserConfig.page_size>0?1:0);
var list=ret.data.firstPage||ret.data.list;
if(!ItemList.isAppending)
{
if(UBB){
for(var i=0;i<list.length;i++){
list[i].description=UBB.toHtml(list[i].description);
}
}
ItemList.cList=list;
}
else
{
for(var i=0;i<list.length;i++){
var item = list[i];
if(UBB){
item.description=UBB.toHtml(item.description);
}
ItemList.cList.push(item);
}
}
//ItemList.showOptionNextPage(ItemList.cPage<ItemList.cTotalPage);
ItemList.showOptionNextPage(false);
if(ItemList.item_list.length>=ItemList.cPage){
ItemList.item_list[ItemList.cPage-1][2]=ItemList.cList;
}
//ItemList.cShowCount=0;
ItemList.showPager('ItemList.loadUnreadItemsPager');
ItemList.ShowList();
return false;
}
ItemList.ShowList=function(showSubFolder){
if(!$('context_itemList'))return;
if(!ItemList.isAppending)
{
$('context_itemList').innerHTML='';
}
if(this.onShowList&&this.onShowList()===false)return;
ItemList.loading=true;
WaitControl.PannelEndWait();
if(ItemList.cList==null){
$('context_itemList').innerHTML+=ItemList.CreateNullItem();
return;
}
if(!ItemList.isAppending)
{
ItemList.enableScrollRead(true);
}
if(ItemList.cList.length==0){
$('context_itemList').innerHTML+=ItemList.CreateNullItem();
}else{
ItemList.fixUnread();
ItemList.setAnalyzerRange(ItemList.cList);
ItemList.CreateShowListItem();
}
var channelInfo=ChannelList.FindChannel(ItemList.cFeedID);
if(channelInfo!=null)
ItemList.setSubscriberNum(channelInfo.subscribeNum);
setTimeout("PageMgr.adjustMainSize()",100);
if(!Actor.UserConfig.item_list_mode&&ItemList.cList&&ItemList.cList.length>0){
if(ItemList.cSelectedItemId==null)
{
ItemList.selectItem(0);
}
}
}
ItemList.CreateShowListItem=function(){
if(ItemList.loading==false)return;
var count=ItemList.cShowCount||0;
var itemList=ItemList.cList;
if(itemList.length<=count){
if(itemList.length >= ItemList.cListTotal)
{
var div=document.createElement('div');
div.className='item_place_holder';
if($('context_itemList'))$('context_itemList').appendChild(div);
setTimeout(function(){
var lastItemHeight = $("item_" + ItemList.cList[ItemList.cList.length - 1].feedItemId).offsetHeight;
if($('context_itemList').offsetHeight - lastItemHeight > 355)
{
div.style.height=($('context_itemList').offsetHeight-lastItemHeight-5) + "px";
}
}, 300);
}
ItemList.isAppending=false;
ItemList.loading=false;
ItemList.cShowCount=itemList.length;
return;
}
try{
if(Actor.UserConfig.item_list_mode){
var html=[];
for(var i=count;i<itemList.length;i++){
if(!itemList[i])continue;
itemList[i]._expandDescr=false;
html.push(ItemList.createItemHtml(i));
html.push('<div class="itemPannel_hr"></div>');
}
ItemList.cShowCount=itemList.length;
ItemList.loading=false;
var panel=$('context_itemList');
if(panel){
if(panel.innerHTML=='')
panel.innerHTML=html.join('');
else panel.appendChild(htmlToFragment(html.join('')));
}
}else{
var html=[];
var fetchItems = [];
var cachedItems = [];
for(var i=count;i<itemList.length&&ItemList.cShowCount-count<5;i++){
if(itemList[i]){
var item=itemList[i];
var cache = ContentCache.get(item.feedItemId);
if(cache)
{
cachedItems.push(item);
}
else
{
var siteInfo = SiteInfo.get(item.feedId);
if(siteInfo && !siteInfo.disabled && siteInfo.auto)
{
var regexp = new RegExp(siteInfo.keyword, "i");
if(item.title.search(regexp) != -1 ||
item.description.search(regexp) != -1)
{
fetchItems.push(item);
}
}
}
item._expandDescr=true;
html.push(ItemList.createItemHtml(i));
html.push('<div class="itemPannel_hr"></div>');
}
ItemList.cShowCount++;
}
var panel=$('context_itemList');
if(!panel)return;
panel.appendChild(htmlToFragment(html.join('')));
for(var i=0;i<cachedItems.length;i++)
{
var item = cachedItems[i];
var container = $("descr_" + item.feedItemId);
var cache = ContentCache.get(item.feedItemId);
if(cache)
{
while (container.firstChild) {
container.removeChild(container.firstChild);
}
container.innerHTML = cache;
}
}
if(fetchItems.length > 0)
{
setTimeout(function()
{
Fetcher.batchRequest(fetchItems);
}, 1);
}
setTimeout(ItemList.CreateShowListItem,10);
}
}catch(ex){
console.log(ex);
}
if(ItemList.cShowCount>=itemList.length){
if(Actor.UserConfig.mark_page_read&&ItemList.status=='feed'){
for(var i=0;i<itemList.length;i++){
var item=ItemList.cList[i];
if(!ItemList.isItemReaded(item)){
ItemList.markItemReaded(i,true);
}
}
}
}
}
var _showPager = ItemList.showPager;
ItemList.showPager=function(functioName)
{
if(Actor.UserConfig.item_list_mode)
{
return _showPager(functioName);
}
else
{
var functioName=functioName||'ItemList.load';
var flipHtml='';
if(ItemList.cListTotal>0){
flipHtml+='<span>前'+ItemList.cList.length+'篇 共'+ItemList.cListTotal+'篇</span> ';
}
$('itemList_footer_filp').innerHTML=flipHtml;
$('itemList_footer_filp').loader=functioName;
if(this.status=="feed"){
ChannelList.setGoItemsView();
}
}
}
var UBB = {
ubbTags:
{
b: [/\[b\](.+?)\[\/b\]/ig, "<b>$1</b>"],
i: [/\[i\](.+?)\[\/i\]/ig, "<i>$1</i>"],
u: [/\[u\](.+?)\[\/u\]/ig, "<u>$1</u>"],
color: [/\[color=['"]?(.+?)['"]?\](.+?)\[\/color\]/ig, "<font color=\"$1\">$2</font>"],
size: [/\[size=['"]?(.+?)['"]?\](.+?)\[\/size\]/ig, "<font size=\"$1\">$2</font>"],
simpleUrl: [/\[url\](.+?)\[\/url\]/ig, "<a href=\"$1\">$1</a>"],
url: [/\[url=['"]?(.+?)['"]?\](.+?)\[\/url\]/ig, "<a href=\"$1\">$2</a>"],
img: [/\[img\](.+?)\[\/img\]/ig, "<img src=\"$1\" />"]
},
toHtml: function(text)
{
for(var tagName in UBB.ubbTags)
{
var tag = UBB.ubbTags[tagName];
text = text.replace(tag[0], tag[1]);
}
return text;
}
};
unsafeWindow.UBB = UBB;
var Fetcher=
{
MAX_ACTIVE_REQUEST: 5,
_active: 0,
_queue: [],
batchRequest: function(items)
{
for(var i=0;i<items.length;i++)
{
var item = items[i];
var container = $("descr_" + item.feedItemId);
/*var cache = ContentCache.get(item.feedItemId);
if(cache)
{
while (container.firstChild) {
container.removeChild(container.firstChild);
}
container.innerHTML = cache;
continue;
}*/
var siteInfo = SiteInfo.get(item.feedId);
if(siteInfo && !siteInfo.disabled)
{
if(this._active >= this.MAX_ACTIVE_REQUEST)
{
this._queue.push([item, container, siteInfo]);
continue;
}
Fetcher.request(item, container, siteInfo);
}
}
},
request: function(item, container, options, redirectURL)
{
if(!container)return;
GM_log([this._active, this._queue.length]);
options = extend({}, options);
var cache = ContentCache.get(item.feedItemId);
if(cache)
{
while (container.firstChild) {
container.removeChild(container.firstChild);
}
container.innerHTML = cache;
return;
}
this._active++;
var url = redirectURL || item.url;
var loading = $x("div[@class='xianguo-plus-loading']", container)[0];
if(!loading)
{
loading = document.createElement("DIV");
loading.className = "xianguo-plus-loading";
loading.innerHTML = "正在载入...";
container.appendChild(loading);
}
GM_log(url);
var options = options || {charset: "utf-8"};
console.log(options);
var mime = 'text/html; charset=';
mime += options.charset;
console.log(mime);
GM_xmlhttpRequest({
method: "GET",
headers: {"User-Agent": navigator.userAgent},
url: url,
overrideMimeType: mime,
onload: function(r)
{
GM_log(r.status);
if(r.status == 200)
{
var text = r.responseText;
text = text.replace(/(<[^>]*?)on(?:(?:un)?load|(?:db)?click|mouse(?:down|up|over|out|move)|key(?:press|down|up)|abort|blur|change|error|focus|re(?:size|set)|select|submit)\s*?=\s*?["'][^"']*?["']/ig, "$1");
text = text.replace(/<\s*?script[^>]*?>[\s\S]*?<\s*?\/script\s*?>/ig, "");
var newUrl = Fetcher.metaRefresh(text);
if(newUrl)
{
if(newUrl.indexOf("://") == -1)
{
newUrl = Fetcher.getURLPrefix(url) + newUrl;
}
Fetcher._requestFinish();
Fetcher.request(item, container, options, newUrl);
return;
}
var html = text.replace(/<!DOCTYPE.*?>/, '').replace(/<html.*?>/, '').replace(/<\/html>.*/, '');
var div = document.createElement("DIV");
div.innerHTML = html;
var contents = document.createElement("DIV");
contents.className = "xianguo-plus-content";
if(!options.template)
{
options.template = "$x{" + options.xpath + "}";
}
if(options.template.indexOf("<xsl:") != -1)
{
contents.appendChild(Fetcher.xsltTransform(options.template, div));
}
else
{
contents.innerHTML = Fetcher.evalTemplate(options.template, div);
}
contents = Fetcher.changeURL(contents, url);
ContentCache.put(item.feedItemId, contents.innerHTML);
loading = null;
if(container)
{
while (container.firstChild) {
container.removeChild(container.firstChild);
}
container.appendChild(contents);
}
}
else if(r.status == 301)
{
var headers = r.responseHeaders;
var groups = /Location:\s*(.+?)\r?\n/.exec(headers);
if(groups && groups[1])
{
var location = groups[1];
Fetcher._requestFinish();
Fetcher.request(item, container, options, location);
return;
}
}
else
{
loading.innerHTML = "载入时发生错误";
GM_log(r.responseHeaders);
}
Fetcher._requestFinish();
},
onerror: function(r)
{
console.error(r);
loading.innerHTML = "载入时发生错误";
Fetcher._requestFinish();
}
});
},
_requestFinish: function()
{
this._active--;
if(this._active < 0) this._active = 0;
if(this._active < this.MAX_ACTIVE_REQUEST && this._queue.length > 0)
{
var args = this._queue.shift();
this.request(args[0], args[1], args[2], args[3]);
}
},
evalTemplate: function(template, node)
{
var div = document.createElement("DIV");
var result = template.replace(/\$x\{(.+?)\}/g, function(str, group1)
{
while(div.firstChild)
{
div.removeChild(div.firstChild);
}
$x(group1, node).forEach(function(item)
{
div.appendChild(item);
});
return div.innerHTML;
});
return result;
},
xsltTransform: function(template, node)
{
var parser = new DOMParser();
var processor = new XSLTProcessor();
template = '<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">' +
template + '</xsl:transform>';
var xslt = parser.parseFromString(template, "text/xml");
processor.importStylesheet(xslt);
return processor.transformToFragment(node, document);
},
metaRefresh: function(html)
{
var groups = /<meta\s+http\-equiv=['"]?refresh['"]?\s+content=['"]?\d+;\s*url=([^>]+?)['"]?\s*>/i.exec(html);
if(groups && groups[1])
{
return groups[1];
}
},
getURLPrefix: function (url)
{
var groups = url.match(/((http|https):\/\/)?([^\/]+)/i);
if(groups && groups[1] && groups[3])
{
return groups[1] + groups[3] + "/";
}
return null;
},
changeURL: function(node, pageUrl)
{
var urlPrefix = this.getURLPrefix(pageUrl);
var aTags = $x('//a', node);
if (aTags)
{
for(var i = 0; i < aTags.length; i++)
{
aTags[i].setAttribute('target', '_blank');
var href = aTags[i].getAttribute('href');
if(href)
{
if(href.indexOf('javascript:') == 0)
{
aTags[i].setAttribute('href', 'javascript:;');
}
else if(href.indexOf('mailto:') == 0)
{
}
else if(href.indexOf('://') == -1)
{
aTags[i].setAttribute('href', urlPrefix + href);
}
}
}
}
var imgTags = $x('//img', node);
if (imgTags)
{
for(var i = 0; i < imgTags.length; i++)
{
var src = imgTags[i].getAttribute('src');
if(src && src.indexOf('://') == -1)
{
imgTags[i].setAttribute('src', urlPrefix + src);
}
}
}
return node;
}
}