diff options
-rw-r--r-- | modules/libDLImage.js | 2 | ||||
-rw-r--r-- | modules/libDLMangaSingleContent.js | 71 | ||||
-rw-r--r-- | pixiv.js | 289 | ||||
-rwxr-xr-x | twittperator/twsidebar.tw | 33 | ||||
-rw-r--r-- | twittperator/twsidebar/chrome/content/twsidebar.xul | 4 |
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);
@@ -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"> |