aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--modules/libDLImage.js2
-rw-r--r--modules/libDLMangaSingleContent.js71
-rw-r--r--pixiv.js289
-rwxr-xr-xtwittperator/twsidebar.tw33
-rw-r--r--twittperator/twsidebar/chrome/content/twsidebar.xul4
5 files changed, 257 insertions, 142 deletions
diff --git a/modules/libDLImage.js b/modules/libDLImage.js
index 63fdcb9..a3d0d3f 100644
--- a/modules/libDLImage.js
+++ b/modules/libDLImage.js
@@ -56,7 +56,7 @@ function downloadImage(){
if(0<JSONMessage.refererUrl.length){
xhrImg.setRequestHeader('Referer',JSONMessage.refererUrl);
};
- if(0<JSONMessage.cookie){
+ if(0<JSONMessage.cookie.length){
xhrImg.setRequestHeader('Cookie',JSONMessage.cookie);
};
xhrImg.send(null);
diff --git a/modules/libDLMangaSingleContent.js b/modules/libDLMangaSingleContent.js
new file mode 100644
index 0000000..5f65856
--- /dev/null
+++ b/modules/libDLMangaSingleContent.js
@@ -0,0 +1,71 @@
+//
+// libDLMangaSingleContent.js
+//
+// libDLMangaSingleContent.js is code for download content of Manga's
+// single page.
+// libDLMangaSingleContent.js is ran on ChromeWorker thread.
+//
+//
+// accept message:
+// {
+// 'pageUrl' :string,
+// 'refererUrl':string,
+// 'cookie' :string
+// }
+//
+// pageUrl : Manga Single Content URL
+// refererUrl : referer string
+// cookie : cookie string
+//
+//
+// send message:
+// {
+// 'status' :string,
+// 'message' :string,
+// 'refererUrl':string,
+// }
+//
+// status : 'normarl' or 'error'
+// message : error message (string) or content text data (HTML)
+// refererUrl : referer string
+//
+var JSONMessage;
+var xhr;
+
+function trueContent(){
+ let content=xhr.responseText;
+ self.postMessage(
+ {'status':'normal','message':content,'refererUrl':JSONMessage.pageUrl}
+ );
+ return;
+};
+
+function falseContent(){
+ self.postMessage({'status':'error','message':'MANGA CONTENT FILE ACCEPT ERROR!!'});
+ return false;
+};
+
+function downloadContent(){
+ xhr=new XMLHttpRequest();
+ xhr.addEventListener("load",trueContent,false);
+ xhr.addEventListener("error",falseContent,false);
+ xhr.open("GET",JSONMessage.pageUrl,false);
+ if(0<JSONMessage.refererUrl.length){
+ xhr.setRequestHeader('Referer',JSONMessage.refererUrl);
+ };
+ if(0<JSONMessage.cookie.length){
+ xhr.setRequestHeader('Cookie',JSONMessage.cookie);
+ };
+ xhr.send(null);
+};
+
+addEventListener("message",function(event){
+ JSONMessage=JSON.parse(event.data);
+ if(JSONMessage.pageUrl===undefined
+ ||JSONMessage.refererUrl===undefined
+ ||JSONMessage.cookie===undefined){
+ self.postMessage({'status':'error','message':'PARAMETA ERROR!!'});
+ return false;
+ }
+ downloadContent();
+}, false);
diff --git a/pixiv.js b/pixiv.js
index 8ee4db4..ba34834 100644
--- a/pixiv.js
+++ b/pixiv.js
@@ -1,6 +1,6 @@
-// INFO //
+// {{{ INFO
var INFO =
-<plugin name="pixiv.js" version="0.7.2"
+<plugin name="pixiv.js" version="0.7.3"
summary="Download image from pixiv"
href="http://github.com/vimpr/vimperator-plugins/blob/master/pixiv.js"
xmlns="http://vimperator.org/namespaces/liberator">
@@ -15,16 +15,18 @@ var INFO =
<spec>:pixiv</spec>
<description>
<p>You can save image from <link topic="http://www.pixiv.net/">pixiv</link> by this plugin.</p>
- <p>You need libDLImage.js under of plugin/modules.</p>
+ <p>You need libDLImage.js and libDLMangaSingleContent.js under of plugin/modules.</p>
<p>You must login pixiv.</p>
</description>
</item>
</plugin>;
+// }}}
commands.addUserCommand(
['pixiv'],
'Save Image File from pixiv',
function(){
+// {{{ environment
let contents=gBrowser.selectedBrowser.contentDocument;
if(contents.domain!="www.pixiv.net"){
liberator.echoerr('This page is not pixiv.');
@@ -38,7 +40,51 @@ commands.addUserCommand(
const Cc=Components.classes;
const Ci=Components.interfaces;
+ let cookie=contents.cookie;
+// }}}
+// {{{ convert to DOM Document from text
+ let getDOMHtmlDocument=function(str){
+ let doc;
+ let range;
+ try{
+ if(document.implementation.createHTMLDocument){
+ doc=document.implementation.createHTMLDocument('');
+ range=doc.createRange();
+ range.selectNodeContents(doc.documentElement);
+ range.deleteContents();
+ doc.documentElement.appendChild(range.createContextualFragment(str));
+ }else{
+ let doctype=document.implementation.createDocumentType(
+ 'html',
+ '-//W3C//DTD HTML 4.01 Transitional//EN',
+ 'http://www.w3.org/TR/html4/loose.dtd'
+ );
+ doc=document.implementation.createDocument(null,'html',doctype);
+ range=doc.createRange();
+ range.selectNodeContents(doc.documentElement);
+ let content=doc.adoptNode(range.createContextualFragment(str));
+ doc.documentElement.appendChild(content);
+ }
+ }catch(e){
+ doc=null;
+ }
+ return doc;
+ };
+// }}}
+
+// {{{ get image id
+ let id;
+ let idTmp=contents.URL.match(/illust_id=(\d+)/i);
+ if(idTmp===null){
+ liberator.echoerr("This page is not image page and not manga page.");
+ return false;
+ }else{
+ id=idTmp[1];
+ }
+// }}}
+
+// {{{ make ChromeWorker
let createWorker=function(fileName){
let ret;
const resourceName="vimp-plugin";
@@ -58,12 +104,14 @@ commands.addUserCommand(
}
return worker;
};
- let worker=createWorker('libDLImage.js');
- if(worker==null){
+// }}}
+// {{{ save image ChromeWorker process
+ let workerImage=createWorker('libDLImage.js');
+ if(workerImage==null){
liberator.echoerr('plugin directory is not found');
return false;
}
- worker.addEventListener('message',function(event){
+ workerImage.addEventListener('message',function(event){
if(event.data.status=='error'){
liberator.echoerr(event.data.message);
return false;
@@ -82,35 +130,40 @@ commands.addUserCommand(
outstream.close();
}
},false);
- worker.addEventListener('error',function(event){
+ workerImage.addEventListener('error',function(event){
liberator.echoerr(event.data.status);
},false);
+// }}}
+// {{{ Recieve Manga Contents ChromeWorker
+ let workerManga=createWorker('libDLMangaSingleContent.js');
+ workerManga.addEventListener('message',function(event){
+ if(event.data.status=='error'){
+ liberator.echoerr(event.data.message);
+ return false;
+ };
+ let domContent=getDOMHtmlDocument(event.data.message);
+ if(domContent){
+ // DOM で画像 URL を取得して画像ファイルの取得リクエストを発行
+ let imgUrl=domContent.getElementsByTagName('img')
+ .item(0).getAttribute('src');
+ let destPath=getDestPath(imgUrl);
+ if(destPath==null){
+ return false;
+ };
+ saveImage(
+ imgUrl,
+ destPath.path,
+ event.data.refererUrl,
+ cookie
+ );
+ }
+ },false);
+ workerManga.addEventListener('error',function(event){
+ liberator.echoerr(event.data.status);
+ },false);
+// }}}
- let id;
- let idTmp=contents.URL.match(/illust_id=(\d+)/i);
- if(idTmp===null){
- liberator.echoerr("This page is not image page and not manga page.");
- return false;
- }else{
- id=idTmp[1];
- }
-
- let baseInfo;
- let scroll;
- let type=contents.getElementsByClassName('works_display').item(0)
- .firstChild.getAttribute('href');
- if(-1!=type.search(/big&illust_id=/i)){
- baseInfo="http://www.pixiv.net/member_illust.php?mode=big&illust_id=";
- scroll='';
- }else if(-1!=type.search(/manga&illust_id=/i)){
- baseInfo="http://www.pixiv.net/member_illust.php?mode=manga&illust_id=";
- scroll='&type=scroll';
- }else{
- liberator.echoerr("This page is not image page and not manga page.");
- return false;
- }
- let cookie=contents.cookie;
-
+// {{{ directory picker
let directoryPicker=function() {
let path;
let fp=Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
@@ -123,55 +176,10 @@ commands.addUserCommand(
};
let saveDirectory=directoryPicker();
if(saveDirectory==null) return false;
+// }}}
- let getDOMHtmlDocument=function(str){
- let doc;
- let range;
- try{
- if(document.implementation.createHTMLDocument){
- doc=document.implementation.createHTMLDocument('');
- range=doc.createRange();
- range.selectNodeContents(doc.documentElement);
- range.deleteContents();
- doc.documentElement.appendChild(range.createContextualFragment(str));
- }else{
- let doctype=document.implementation.createDocumentType(
- 'html',
- '-//W3C//DTD HTML 4.01 Transitional//EN',
- 'http://www.w3.org/TR/html4/loose.dtd'
- );
- doc=document.implementation.createDocument(null,'html',doctype);
- range=doc.createRange();
- range.selectNodeContents(doc.documentElement);
- let content=doc.adoptNode(range.createContextualFragment(str));
- doc.documentElement.appendChild(content);
- }
- }catch(e){
- doc=null;
- }
- return doc;
- };
-
- let getImageUrl=function(pageContents){
- let url;
- let htmldoc=getDOMHtmlDocument(pageContents);
- if(htmldoc){
- if(0<htmldoc.getElementsByTagName('img').length)
- url=htmldoc.getElementsByTagName('img').item(0).getAttribute('src');
- else
- url='';
- }else{
- let s=pageContents.indexOf('src="')+5;
- let e=pageContents.indexOf('"',s);
- url=pageContents.substr(s,e-s);
- }
- return url;
- };
-
- let imgUrl;
- let destPath;
-
- let saveImage=function(){
+// {{{ send request save image
+ let saveImage=function(imgUrl,savePath,referer,cookie){
let objMessage={
imageUrl :'',
savePath :'',
@@ -179,13 +187,15 @@ commands.addUserCommand(
cookie :''
};
objMessage.imageUrl=imgUrl;
- objMessage.savePath=destPath.path;
- objMessage.refererUrl=contents.URL;
+ objMessage.savePath=savePath;
+ objMessage.refererUrl=referer;
objMessage.cookie=cookie;
let JSONmessage=JSON.stringify(objMessage);
- worker.postMessage(JSONmessage);
+ workerImage.postMessage(JSONmessage);
};
+// }}}
+// {{{ get destnation fullpath name
let getDestPath=function(url){
let fname=url.substr(url.lastIndexOf('/')+1);
if(fname.lastIndexOf('?')!=-1){
@@ -208,74 +218,82 @@ commands.addUserCommand(
}
return newPath;
};
+// }}}
+
+// {{{ save single image file
+ let getImageUrl=function(pageContents){
+ let url;
+ let htmldoc=getDOMHtmlDocument(pageContents);
+ if(htmldoc){
+ if(0<htmldoc.getElementsByTagName('img').length)
+ url=htmldoc.getElementsByTagName('img').item(0).getAttribute('src');
+ else
+ url='';
+ }else{
+ url=pageContents.match(/http:\/\/img[0-9]{2}\.pixiv\.net\/img\/[0-9a-z_]+\/[0-9]+\.jpg|http:\/\/img[0-9]{2}\.pixiv\.net\/img\/[0-9a-z_]+\/[0-9]+\.png/i);
+ }
+ return url;
+ };
let saveImageFile=function(){
- imgUrl=getImageUrl(xhrImgInfo.responseText);
+ let imgUrl=getImageUrl(xhrImgInfo.responseText);
if(0<imgUrl.length){
- destPath=getDestPath(imgUrl);
+ let destPath=getDestPath(imgUrl);
if(destPath==null){
return false;
};
- saveImage();
+ saveImage(
+ imgUrl,
+ destPath.path,
+ contents.URL,
+ cookie
+ );
}else{
liberator.echoerr("You should login pixiv :<");
};
};
+// }}}
- let getImageUrls=function(pageContents){
- const BIG='_big';
- let url=[];
- let strScript;
- let fst,snd;
- let strFst='';
- let strSnd='';
- let tblElm;
- let i;
- let htmldoc=getDOMHtmlDocument(pageContents);
- if(htmldoc){
- let max=htmldoc.getElementsByClassName('image-container').length;
- for(i=0;i<max;i++){
- strScript=htmldoc.getElementsByClassName('image-container').item(i)
- .getElementsByTagName('script').item(0)
- .childNodes.item(0).nodeValue;
- fst=strScript.search(/unshift/i)+'unshift'.length+2;
- snd=strScript.lastIndexOf('_');
- strFst=strScript.substr(fst,snd-fst);
-
- fst=snd;
- snd=strScript.indexOf("'",fst);
- strSnd=strScript.substr(fst,snd-fst);
-
- url.push(strFst+BIG+strSnd);
- }
- }else{
- url.length=0;
- }
- return url;
+// {{{ save manga image file
+ let requestMangaSingleContent=function(url,ref){
+ let objMessage={
+ pageUrl :'',
+ refererUrl:'',
+ cookie :''
+ };
+ objMessage.pageUrl=url;
+ objMessage.refererUrl=ref;
+ objMessage.cookie=cookie;
+ let JSONmessage=JSON.stringify(objMessage);
+ workerManga.postMessage(JSONmessage);
};
- let imgUrls;
let saveMangaFiles=function(){
- imgUrls=getImageUrls(xhrImgInfo.responseText);
- if(0<imgUrls.length){
- let i;
- let max=imgUrls.length;
- for(i=0;i<max;i++){
- imgUrl=imgUrls[i];
- pnt=imgUrl.lastIndexOf('?');
- if(-1!=pnt){
- imgUrl=imgUrl.substr(0,pnt);
- }
- destPath=getDestPath(imgUrl);
- if(destPath==null){
- continue;
- }
- saveImage();
+ let htmldoc=getDOMHtmlDocument(xhrImgInfo.responseText);
+ if(htmldoc){
+ let max=htmldoc.getElementsByClassName('image-container').length;
+ for(var i=0;i<max;i++){
+ requestMangaSingleContent(
+ url.replace('manga','manga_big').replace('type=scroll','page=')+i,
+ url.replace('&type=scroll','')
+ );
}
- }else{
- liberator.echoerr("Not found image data on the manga page.");
}
};
+// }}}
+
+// {{{ first XMLHttpRequest
+ let url;
+ let type=contents.getElementsByClassName('works_display')
+ .item(0).firstChild.getAttribute('href');
+ if(-1!=type.search(/big&illust_id=/i)){
+ url=contents.documentURI.replace('medium','big');
+ }else if(-1!=type.search(/manga&illust_id=/i)){
+ url=contents.documentURI.replace('medium','manga')+'&type=scroll';
+ }else{
+ liberator.echoerr("This page is not image page and not manga page.");
+ return false;
+ }
let trueImgInfo=function(){
if(-1!=type.search(/big&illust_id=/i)){
@@ -299,10 +317,11 @@ commands.addUserCommand(
xhrImgInfo.addEventListener("load",trueImgInfo,false);
xhrImgInfo.addEventListener("error",falseImgInfo,false);
xhrImgInfo.QueryInterface(Ci.nsIXMLHttpRequest);
- xhrImgInfo.open("GET",baseInfo+id+scroll,true);
+ xhrImgInfo.open("GET",url,true);
xhrImgInfo.setRequestHeader('Referer',contents.URL);
xhrImgInfo.setRequestHeader('Cookie',cookie);
xhrImgInfo.send(null);
+// }}}
},
{},
true
diff --git a/twittperator/twsidebar.tw b/twittperator/twsidebar.tw
index f6af3af..9545965 100755
--- a/twittperator/twsidebar.tw
+++ b/twittperator/twsidebar.tw
@@ -43,6 +43,9 @@ liberator.modules.TWAnekoSB = ANekoSB = (function () {
// 地震ツイートの本文に場所をくっつける
earthquake: true,
+
+ // サイドバーを閉じても機能を停止しない
+ dontStop: true
};
// 日本語判定
@@ -202,6 +205,9 @@ liberator.modules.TWAnekoSB = ANekoSB = (function () {
Tweets.splice(Config.listMax);
}
+ if (sidebarClosed)
+ return;
+
let screenName = Config.screenName;
let my = (msg.retweeted_status && msg.retweeted_status.user.screen_name === screenName)
||
@@ -466,6 +472,7 @@ liberator.modules.TWAnekoSB = ANekoSB = (function () {
let Store = storage.newMap("twittperator-anekos-sb", {store: true});
let started = false;
let readyToStart = false;
+ let sidebarClosed = true;
let Tweets = __context__.Tweets;
if (!Tweets)
@@ -473,7 +480,20 @@ liberator.modules.TWAnekoSB = ANekoSB = (function () {
let added = {};
- function start () { // {{{
+ function start (isOpen, silent) { // {{{
+ function restore () {
+ Array.slice(Tweets).reverse().forEach(makeOnMsg(false));
+ }
+
+ if (silent && (started || readyToStart))
+ return;
+
+ if (isOpen && sidebarClosed) {
+ sidebarClosed = false;
+ restore();
+ return;
+ }
+
if (readyToStart)
return;
if (started)
@@ -484,7 +504,7 @@ liberator.modules.TWAnekoSB = ANekoSB = (function () {
setTimeout(
function () {
readyToStart = false;
- Array.slice(Tweets).reverse().forEach(makeOnMsg(false));
+ restore();
plugins.twittperator.ChirpUserStream.addListener(added.chirp = makeOnMsg(true, 'chirp'));
plugins.twittperator.TrackingStream.addListener(added.filter = makeOnMsg(true, 'filter'));
},
@@ -492,10 +512,15 @@ liberator.modules.TWAnekoSB = ANekoSB = (function () {
);
} // }}}
- function stop () { // {{{
+ function stop (isClose) { // {{{
if (!started)
return liberator.echoerr('TWAnekoSB has not been started!');
+ if (isClose && Config.dontStop) {
+ sidebarClosed = true;
+ return;
+ }
+
plugins.twittperator.ChirpUserStream.removeListener(added.chirp);
plugins.twittperator.TrackingStream.removeListener(added.filter);
Store.set("history", Tweets);
@@ -513,7 +538,7 @@ liberator.modules.TWAnekoSB = ANekoSB = (function () {
addCommands();
- return {start: start, stop: stop};
+ return {start: start, silentStart: function () start(false, true), stop: stop};
})();
diff --git a/twittperator/twsidebar/chrome/content/twsidebar.xul b/twittperator/twsidebar/chrome/content/twsidebar.xul
index 69ab965..abfac9c 100644
--- a/twittperator/twsidebar/chrome/content/twsidebar.xul
+++ b/twittperator/twsidebar/chrome/content/twsidebar.xul
@@ -3,8 +3,8 @@
<?xml-stylesheet href="chrome://browser/skin/browser.css" type="text/css"?>
<?xml-stylesheet href="chrome://twsidebar/content/twsidebar.css" type="text/css"?>
<page id="tw-sidebar-page" title="Twitter Sidebar"
- onload="window.parent.liberator.modules.TWAnekoSB.start()"
- onunload="window.parent.liberator.modules.TWAnekoSB.stop()"
+ onload="window.parent.liberator.modules.TWAnekoSB.start(true)"
+ onunload="window.parent.liberator.modules.TWAnekoSB.stop(true)"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" >
<vbox flex="1">
<tabbox id="tw-anekos-sb-tabbox" flex="1">