- // ==UserScript==
- // @name pixiv_sort_by_popularity(working again)
- // @name:zh-CN pixiv_sort_by_popularity
- // @name:zh-TW pixiv_sort_by_popularity
- // @name:ja pixiv_sort_by_popularity
- // @namespace pixiv_sort_by_popularity
- // @supportURL https://github.com/zhuzemin
- // @description non premium menber use "Sort by popularity"
- // @description:zh-CN non premium menber use "Sort by popularity"
- // @description:zh-TW non premium menber use "Sort by popularity"
- // @description:ja non premium menber use "Sort by popularity"
- // @include https://www.pixiv.net/*/tags/*
- // @include https://www.pixiv.net/tags/*
- // @version 1.09
- // @run-at document-start
- // @author zhuzemin
- // @license Mozilla Public License 2.0; http://www.mozilla.org/MPL/2.0/
- // @license CC Attribution-ShareAlike 4.0 International; http://creativecommons.org/licenses/by-sa/4.0/
- // @grant GM_xmlhttpRequest
- // @grant GM_registerMenuCommand
- // @grant GM_setValue
- // @grant GM_getValue
- // @connect-src workers.dev
- // ==/UserScript==
- var config = {
- 'debug': false
- }
- var debug = config.debug ? console.log.bind(console) : function () {
- };
-
- //this userscript desire for free member use "Sort by popularity"
-
- //default
- //pixiv search request through this url will use my cookie.
- var cloudFlareUrl='https://proud-surf-e590.zhuzemin.workers.dev/ajax/';
-
- //Obejct use for xmlHttpRequest
- class requestObject{
- constructor(originUrl,page,order) {
- this.method = 'GET';
- this.url = cloudFlareUrl+originUrl
- .replace(/(https:\/\/www\.pixiv\.net\/)(\w*\/)?tags\/([^\/]*)\/(\w*)\?([^\/\?]*)/,
- function(match, $1, $2,$3,$4,$5, offset, original){ return $1+'ajax/search/'+$4+'/'+$3+'?'+$5;})
- .replace(/p=\d*/,'').replace(/order=[_\w]*/,'')+'&p='+page+'&order='+order;
- this.data=null,
- this.headers = {
- 'User-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0',
- 'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'
- //'Accept': 'application/atom+xml,application/xml,text/xml',
- //'Referer': window.location.href,
- };
- this.charset = 'text/plain;charset=utf8';
- this.package=null;
- }
- }
-
- var btn;
-
- // prepare UserPrefs
- setUserPref(
- 'cloudFlareUrl',
- cloudFlareUrl,
- 'Set cloudFlareUrl',
- `cloudFlareUrl only working on "Sort by popularity"`,
- ','
- );
-
-
- //for override fetch, I think override function sure insert to page, otherwise userscript don't have permission modified fetch in page?
- function addJS_Node (text)
- {
- var scriptNode = document.createElement ('script');
- scriptNode.type = "text/javascript";
- if (text) scriptNode.textContent = text;
-
- var targ = document.getElementsByTagName('head')[0] || d.body || d.documentElement;
- targ.appendChild (scriptNode);
- }
-
-
-
- //override fetch
- function intercept(){
- //insert override function to page
- addJS_Node(`
- var newData;
- var interceptEnable;
- var newUrl;
- var constantMock = window.fetch;
- window.fetch = function() {
- arguments[0]=newUrl;
- //console.log(arguments);
-
- return new Promise((resolve, reject) => {
- constantMock.apply(this, arguments)
- .then((response) => {
- if(interceptEnable&&/https:\\/\\/www\\.pixiv\\.net\\/ajax\\/search\\//.test(response.url)){
- var blob = new Blob([newData], {type : 'application/json'});
- //console.log(newData);
-
- var newResponse=new Response(
- blob, {
- status: response.status,
- statusText: response.statusText,
- headers: response.headers
- });
- //console.log(newResponse);
- response=newResponse;
- interceptEnable=false;
- }
- resolve(response);
- })
- .catch((error) => {
- reject(response);
- })
- });
- }
- `);
- //here is script end,
- //in console ,log show fetch response body has been changed <--- not very sure
- //and page have react ---> stay blank for ever
- //my confuse is: even comment "return data" (line:93), page still return blank,
- //that makes me wonder: maybe this override function miss something.
- //if my terrible code can be understanding somehow,
- //and knoa san have nothing else todo in leisure time,
- //knoa san can you take while, look my newbie problem?
- //of cource if too painful read my code, I totally understand!
- //knoa san can read to here already be my greatest honor, and I'm very happy!
- }
-
- //userscript entry
- var init=function(){
- //create button
- if(window.self === window.top){
- debug("init");
- cloudFlareUrl=GM_getValue('cloudFlareUrl')||cloudFlareUrl;
- intercept();
- var nav=document.querySelector('nav');
- btn =document.createElement('button');
- btn.innerHTML='Sort by popularity';
- btn.addEventListener('click',sortByPopularity);
- nav.insertBefore(btn,null);
- select=document.createElement('select');
- select.id='sortByPopularity';
- var optionObj={
- 'Popular with all':'popular_d',
- 'Popular (male)':'popular_male_d',
- 'Popular (female)':'popular_female_d'
- }
- for(var key of Object.keys(optionObj)){
- var option=document.createElement('option');
- option.innerHTML=key;
- option.value=optionObj[key];
- select.insertBefore(option,null);
- }
- nav.insertBefore(select,null);
- }
- }
-
- window.addEventListener('load', init);
-
- //get current search word, then use xmlHttpRequest get response(from my server)
- function sortByPopularity(e) {
- btn.innerHTML='Searching...'
- try{
- var page;
- //var matching=window.location.href.match(/https:\/\/www\.pixiv\.net\/(\w*\/)?tags\/(.*)\/\w*\?(order=[^\?&]*)?&?(mode=(\w\d*))?&?(p=(\d*))?/);
- debug(e.target.tagName);
- if(/(\d*)/.test(e.target.textContent)&&(e.target.tagName.toLowerCase()=='span'||e.target.tagName.toLowerCase()=="a")){
- page=e.target.textContent.match(/(\d*)/)[1];
- }
- else if(e.target.tagName.toLowerCase()=='svg'||e.target.tagName.toLowerCase()=='polyline'){
- //debug('e.target.parentElement.tagName: '+e.target.parentElement.tagName);
- if(e.target.parentElement.tagName.toLowerCase()=='a'){
- page=e.target.parentElement.href.match(/p=(\d*)/)[1];
-
- }
- else {
- page=e.target.parentElement.parentElement.href.match(/p=(\d*)/)[1];
-
- }
- }
- //for test
- /*else if(matching[7]!=null){
- page=matching[7];
- }*/
- else{
- page=1;
- }
- page=parseInt(page);
- debug('page: '+page);
- var order=document.querySelector('#sortByPopularity').value;
- var obj=new requestObject(window.location.href,page,order);
- debug('JSON.stringify(obj): '+JSON.stringify(obj));
- request(obj,function (responseDetails) {
- debug("responseDetails.response: "+JSON.stringify(responseDetails.response));
- unsafeWindow.newData=JSON.stringify(responseDetails.response,null,2);
- unsafeWindow.interceptEnable=true;
- unsafeWindow.newUrl=obj.url.replace(cloudFlareUrl+'https://www.pixiv.net','');
- //trigger fetch by click "Newest" or "Oldest"
- var spanList=document.querySelectorAll('span');
- for(var span of spanList){
- if(/(Newest)|(Oldest)|(按最新排序)|(按旧|舊排序)|(新しい順)|(古い順)|(최신순)|(과거순)/.test(span.textContent)){
- if(span.parentElement.tagName.toLowerCase()=='a'){
- span.parentElement.click();
- break;
- }
- }
- }
- var interval=setInterval(function () {
- var nav=document.querySelectorAll('nav')[1];
- if(nav!=null){
- nav.addEventListener('click',sortByPopularity);
- if(page<=7&&page>1){
- //nav button "1" text -> current page number
- nav.childNodes[1].childNodes[0].innerText=page;
- //nav button "1" href -> current page href
- nav.childNodes[1].href=nav.childNodes[page].href;
- //current page button text -> "1"
- nav.childNodes[page].innerText=1;
- //current page button href -> origin nav button "1" href
- nav.childNodes[page].href=nav.childNodes[0].href;
- //switch two button positon
- nav.insertBefore(nav.childNodes[1],nav.childNodes[page]);
- nav.insertBefore(nav.childNodes[page],nav.childNodes[1]);
-
- }
- else if(page>7){
- var currentPositionInNav=page%7;
- debug("currentPositionInNav: "+currentPositionInNav);
- var buttonStartNumber=page-currentPositionInNav;
- debug("buttonStartNumber: "+buttonStartNumber);
- var navButtonCount=1;
- //switch two button positon
- nav.insertBefore(nav.childNodes[1],nav.childNodes[currentPositionInNav+1]);
- nav.insertBefore(nav.childNodes[currentPositionInNav+1],nav.childNodes[1]);
- for(var i=buttonStartNumber;i<=(buttonStartNumber+6);i++){
- debug("navButtonCount: "+navButtonCount);
- debug("i: "+i);
- nav.childNodes[navButtonCount].childNodes[0].innerText=i;
- nav.childNodes[navButtonCount].href=nav.childNodes[8].href.replace(/p=\d*/,'p='+(i));
- navButtonCount++;
- }
- }
- if(page!=1){
- //display previous button
- nav.childNodes[0].style='opacity:1!important;';
- //previous button href
- nav.childNodes[0].href=nav.childNodes[8].href.replace(/p=\d*/,'p='+(page-1));
- //next button href
- nav.childNodes[8].href=nav.childNodes[8].href.replace(/p=\d*/,'p='+(page+1));
-
- }
- btn.innerHTML='Sort by popularity';
- clearInterval(interval);
-
- }
- },2000);
- });
-
- }
- catch (e) {
- debug('[Error]: '+e)
- }
-
- }
- function request(object,func) {
- GM_xmlhttpRequest({
- method: object.method,
- url: object.url,
- headers: object.headers,
- responseType: 'json',
- overrideMimeType: object.charset,
- timeout: 60000,
- //synchronous: true
- onload: function (responseDetails) {
- debug(responseDetails);
- //Dowork
- func(responseDetails);
- },
- ontimeout: function (responseDetails) {
- //Dowork
- func(responseDetails);
-
- },
- ononerror: function (responseDetails) {
- debug(responseDetails);
- //Dowork
- func(responseDetails);
-
- }
- });
- }
- function setUserPref(varName, defaultVal, menuText, promtText, sep){
- GM_registerMenuCommand(menuText, function() {
- var val = prompt(promtText, GM_getValue(varName, defaultVal));
- if (val === null) { return; } // end execution if clicked CANCEL
- // prepare string of variables separated by the separator
- if (sep && val){
- var pat1 = new RegExp('\\s*' + sep + '+\\s*', 'g'); // trim space/s around separator & trim repeated separator
- var pat2 = new RegExp('(?:^' + sep + '+|' + sep + '+$)', 'g'); // trim starting & trailing separator
- //val = val.replace(pat1, sep).replace(pat2, '');
- }
- //val = val.replace(/\s{2,}/g, ' ').trim(); // remove multiple spaces and trim
- GM_setValue(varName, val);
- // Apply changes (immediately if there are no existing highlights, or upon reload to clear the old ones)
- //if(!document.body.querySelector(".THmo")) THmo_doHighlight(document.body);
- //else location.reload();
- });
- }